2017-01-12 1 views
0

Ist es möglich, einen Teil der Abfrage basierend auf Ausdruck zu erstellen?Dynamisch komponieren auswählen mit Linq zu SQL (EF6)

public List<SelectListItem> GetSelectedListFromEntity<T>(Expression<Func<T, object>> property) where T : BaseEntity<int> 
    { 
     var result = _repository.Query<T>().Select(p => new SelectListItem() 
     { 
      Text = property, //? (in simple case it looks like: p.Name + p.Category) 
      Value = p.Id.ToString(), 
     ).ToList(); 

     return result; 
    } 

Für:

var result = GetSelectedListFromEntity<Product>(p => p.Name + p.Category); 
+1

unklar, was Sie fragen Bitte klären Sie Ihr spezifisches Problem oder fügen Sie zusätzliche Details hinzu, um genau zu markieren, was Sie brauchen. Wie es derzeit geschrieben wird, ist es schwer zu sagen, was genau Sie fragen. – Nkosi

+0

mm wie Sie geschrieben haben .. es sieht die Expression > Eigenschaft muss ein Objekt zurückgeben .. ist es? –

+0

@Awesome, rufen Sie die Funktion auf dem Element Text = Eigenschaft (p) .ToString() '. Sie fragen im Grunde, wie Sie den Anzeigetext für die Auswahl konstruieren? – Nkosi

Antwort

4

Wenn Sie es mit einem DB-Provider, etwas arbeiten möchten geben Ihnen einen IQueryable Sie etwas mit Ausdruck Bäume wie dies tun können.

Unter diesen Klassen:

public class BaseEntity 
{ 
    public int Id { get; set;} 
} 

public class Product : BaseEntity 
{ 
    public string Name { get; set; } 
    public string Category { get; set; } 
} 

Jetzt müssen Sie eine Funktion um den Ausdruck zu machen:

public Expression<Func<T, SelectListItem>> CreateExpression<T>(Expression<Func<T, string>> textExp) where T : BaseEntity 
{ 
    var arg = textExp.Parameters.First();  
    var param = new ParameterExpression[] { arg }; 
    var body = Expression.MemberInit(
     Expression.New(typeof(SelectListItem)), 
     Expression.Bind(typeof(SelectListItem).GetMember("Text").First(), textExp.Body), 
     Expression.Bind(typeof(SelectListItem).GetMember("Value").First(), 
      Expression.Call(
       Expression.PropertyOrField(arg, "Id"), 
       "ToString", 
       new Type[0] 
       ))); 
    var exp = Expression.Lambda(body, param); 
    return (Expression<Func<T, SelectListItem>>)exp; 
} 

In C# 6 ist es besser Praxis diese magischen Saiten mit nameof() zu ersetzen. Dann endlich können Sie es mit so etwas wie dies nennen:

var items = new List<Product> { new Product { Id = 0, Name = "Test", Category = "Cat" } }; 

var result = items.AsQueryable().Select(CreateExpression<Product>(p => p.Name + p.Category)).ToList(); 

Nun, solange Sie Anbieter mit der Herstellung SelectListItems bewältigen Linq können Sie sollten in Ordnung sein.

+0

dies ist genau das, was ich will! Vielen Dank. –