Contexte: l'utilisateur doit être en mesure de choisir aussi efficacement que possible un DB-Table/Model/Class et filtrer/trier/afficher toutes les propriétés publiques de celui-ci.Charger l'accesseur Func par réflexion dans le dictionnaire
Les noms peuvent être interrogés par l'API de réflexion, mais je me demandais, si ces accès peuvent être stockés et devenir plus efficace de cette façon?
Cet exemple montre comment cela peut être fait, mais à chaque accès, il va interroger la réflexion-api dans la fonction.
public class TestClass // the Model or Table
{
public int Id { get; set; }
public string Name { get; set; }
}
public static void Main(string[] args)
{
var testClasses = new TestClass[] {
new TestClass { Id = 1 , Name = "1" } ,
new TestClass { Id = 2 , Name = "2" } ,
new TestClass { Id = 3 , Name = "3" } ,
};
var propertyInfos = typeof(TestClass).GetProperties();
var map = new Dictionary<string,Func<object,object>>(); // Func<object,object> -> Func takes an instance of the class and return a public property
// load the map once
foreach(var propertyInfo in propertyInfos)
{
Func<object,object> func = x => propertyInfo.GetValue(x);
map.Add(propertyInfo.Name , func);
}
// get the names by user-input
var names = propertyInfos.Select(x => x.Name).ToArray();
// load the properties by name
foreach(var testClass in testClasses)
{
Console.WriteLine($"{testClass.Id} - {testClass.Name}");
foreach(var name in names)
{
var func = map[ name ];
var value = func(testClass); // this is 'bad' as it uses reflection every invokation
Console.WriteLine($"\t{name} = {value}");
}
}
}
Ma question serait la suivante: peut-il Dictionnaire
var map = new Dictionary<string,Func<object,object>> {
{ "Id" , x => (x as TestClass).Id } ,
{ "Name" , x => (x as TestClass).Name } ,
};
automatiquement créé en fournissant seulement le type (et sans utiliser la réflexion sur chaque invokation)?
Notez que si vous faites ce que vous suggérez, vous allez filtrer les lignes C# -side ... Vous ne produirez pas une requête SQL qui utilise un 'WHERE'. Votre code C# recevra toutes les lignes de la table, puis les filtrera :-( – xanatos
En général, comment le faire "correctement" dépend de la façon dont vous faites les requêtes à la base de données ... Si vous utilisez un * Ado.NET * ('DbConnection' ou' SqlConnection' avec 'DbCommand' ou' SqlCommand') et écrire des requêtes avec des chaînes puis il y a un ensemble de solutions.Si vous utilisez Entity Framework, Linq-to-SQL, NHibernate, ??? – xanatos
Bon point Malheureusement, je dois charger l'enregistrement en mémoire, car je dois les pré-traiter avant le filtrage (et je ne peux pas changer la représentation de la table sous-jacente ni stocker les versions prétraitées dans une autre table). même possible, comme une «procédure stockée pour C# Funcs» – nonsensation