2009-06-19 7 views
0

J'utilise DbLinq qui devrait être l'équivalent de Linq2SQL pour cette question. Je dois générer une requête Linq2SQL où je spécifie les colonnes que je veux renvoyer à l'exécution. Je peux y parvenir en utilisant les méthodes d'extension de Dynamic Linq, mais je n'arrive pas à extraire le résultat.Accès Linq résultat contenu dans une classe dynamique

string someProperty = "phonenumber"; 
string id = "1234"; 

Table<MyClass> table = context.GetTable<MyClass>(); 
var queryResult = (from item in table where item.Id == id select item).Select("new (" + someProperty + ")"); 

L'expression LINQ génère le SQL correct de:

select phonenumber from mytable where id = '1234' 

Et dans le débogueur je peux voir la valeur est assis là phonenumber dans la vue des résultats. Le problème est que je ne peux pas calculer comment obtenir la valeur phonenumber de l'objet queryResult? Le type de QueryResult est:

QueryProvider<DynamicClass1> 

Edit: Je découvert une façon de le faire, mais il semble très brut.

IEnumerator result = (from item in table where item.Id == id select item).Select("new (" + someProperty + ")").GetEnumerator(); 
result.MoveNext(); 
var resultObj = result.Current; 
PropertyInfo resultProperty = resultObj.GetType().GetProperty(someProperty); 
Console.WriteLine(resultProperty.GetValue(resultObj, null)); 

Peut-être que quelqu'un connaît une manière plus propre?

Répondre

0

La solution était:

string someProperty = "phonenumber"; 
PropertyInfo property = typeof(T).GetProperty(propertyName); 
string id = "1234"; 
Table<MyClass> table = context.GetTable<MyClass>(); 
Expression<Func<T, Object>> mySelect = DynamicExpression.ParseLambda<T, Object>(property.Name); 
var query = (from asset in table where asset.Id == id select asset).Select(mySelect); 
return query.FirstOrDefault(); 
0

Linq utilise une méthode d'exécution différée pour obtenir des données. Deferred execution signifie que l'évaluation d'une expression est retardée jusqu'à ce que sa valeur effective soit réellement requise.

Dans votre cas, queryResult est un objet IEnumerable, ce qui signifie qu'aucune donnée n'a encore été évaluée. Vous pouvez évaluer l'objet queryResult en appelant result.ToList() ou result.ToDictionary() ou toute autre méthode qui retournera un objet avec des types de données non IEnumerable.

J'espère que cela vous sera utile.

+0

Le problème il y a la méthode dynamique d'extension LINQ Select retourne un objet IQueryable et non un objet IQueryable . Le résultat de cela n'est aucune des méthodes pratiques ToList etc. sont disponibles. Bien que je suppose que finalement ces méthodes doivent juste utiliser le IEnumberator sous le capot de toute façon. – sipwiz

0

Les aspects dynamiques de votre solution vous forcent à utiliser la réflexion. Vous pouvez utiliser la propriété "ElementType" de l'IQueryable plutôt que d'obtenir le premier élément et de lire son type. Ensuite, une boucle comme cela peut être mieux:

var result = (from item in table where item.Id == id select item).Select("new (" + someProperty + ")"); 
PropertyInfo resultProperty = result.ElementType.GetProperty(someProperty); 
foreach (var resultObj in result) 
{ 
    var value = resultProperty.GetValue(resultObj, null); 
} 

Court de créer des fonctions pour faire partie de ce travail pour vous, il n'y a pas grand-chose à améliorer. Le compilateur ne sait simplement pas ce qu'il y a dans l'objet, puisqu'il est dynamique. Donc, toute la gentillesse du code non-réfléchissant est indisponible.