Entity Framework 4.1 simple dynamic expression for object.property = value

不打扰是莪最后的温柔 提交于 2019-12-22 00:46:18

问题


I know there is a way to use Expressions and Lambdas to accomplish this but I having a hard time piecing it all together. All I need is a method that will dynamically query an Entity Framework DBSet object to find the row where the propery with the given name matches the value.

My context:

public class MyContext : DbContext
{
    public IDbSet<Account> Accoounts{ get { return Set<Account>(); } } 
}

The method that I'm looking to write:

public T Get<T>(string property, object value) : where T is Account
{...}

I would rather not have to use Dynamic SQL to accomplish this so no need to suggest it because I already know it's possible. What I'm really looking for is some help to accomplish this using Expressions and Lambdas

Thanks in advance, I know it's brief but it should be pretty self-explanatory. Comment if more info is needed


回答1:


I'm trying to avoid dynamic linq as much as possible because the main point of linq is strongly typed access. Using dynamic linq is a solution but it is exactly the oppose of the linq purpose and it is quite close to using ESQL and building the query from sting concatenation. Anyway dynamic linq is sometimes real time saver (especially when it comes to complex dynamic ordering) and I successfully use it in a large project with Linq-to-Sql.

What I usually do is defining some SearchCriteria class like:

public class SearchCriteria
{
     public string Property1 { get; set; }
     public int? Property2 { get; set; }
}

And helper query extension method like:

public static IQueryable<SomeClass> Filter(this IQueryable<SomeClass> query, SearchCriteria filter)
{
     if (filter.Property1 != null) query = query.Where(s => s.Property1 == filter.Property1);
     if (filter.Property2 != null) query = query.Where(s => s.Property2 == filter.Property2);
     return query;
}

It is not generic solution. Again generic solution is for some strongly typed processing of classes sharing some behavior.

The more complex solution would be using predicate builder and build expression tree yourselves but again building expression tree is only more complex way to build ESQL query by concatenating strings.




回答2:


Dynamic Linq may be an option. Specify your criteria as a string and it will get built as an expression and ran against your data;

An example from something I have done;

var context = new DataContext(ConfigurationManager.ConnectionStrings["c"].ConnectionString);
var statusConditions = "Status = 1";
var results = (IQueryable)context.Contacts.Where(statusConditions);

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx




回答3:


Here's my implementation:

public T Get<T>(string property, object value) : where T is Account
{
    //p
    var p = Expression.Parameter(typeof(T));

    //p.Property
    var propertyExpression = Expression.Property(p, property);

    //p.Property == value
    var equalsExpression = Expression.Equal(propertyExpression, Expression.Constant(value));

    //p => p.Property == value
    var lambda = Expression.Lambda<Func<T,bool>>(equalsExpression, p);

    return context.Set<T>().SingleOrDefault(lambda);
}

It uses EF 5's Set<T>() method. If you are using a lower version, you'll need to implement a way of getting the DbSet based on the <T> type.

Hope it helps.



来源:https://stackoverflow.com/questions/6499995/entity-framework-4-1-simple-dynamic-expression-for-object-property-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!