Linq 实体框架4.1 object.property=value的简单动态表达式
我知道有一种方法可以使用表达式和lambda来实现这一点,但我很难将它们拼凑在一起。我所需要的只是一个方法,该方法将动态查询Entity Framework DBSet对象,以查找具有给定名称的属性与值匹配的行 我的背景:Linq 实体框架4.1 object.property=value的简单动态表达式,linq,entity-framework,ef-code-first,Linq,Entity Framework,Ef Code First,我知道有一种方法可以使用表达式和lambda来实现这一点,但我很难将它们拼凑在一起。我所需要的只是一个方法,该方法将动态查询Entity Framework DBSet对象,以查找具有给定名称的属性与值匹配的行 我的背景: public class MyContext : DbContext { public IDbSet<Account> Accoounts{ get { return Set<Account>(); } } } 公共类MyContext:D
public class MyContext : DbContext
{
public IDbSet<Account> Accoounts{ get { return Set<Account>(); } }
}
公共类MyContext:DbContext
{
公共IDbSet帐户{get{return Set();}}
}
我想写的方法是:
public T Get<T>(string property, object value) : where T is Account
{...}
publictget(字符串属性,对象值):其中T是Account
{...}
我宁愿不必使用动态SQL来实现这一点,所以无需提出建议,因为我已经知道这是可能的。我真正想要的是使用表达式和lambda来帮助实现这一点
提前谢谢,我知道它很简短,但它应该是相当不言自明的。注释如果需要更多信息动态Linq可能是一个选项。将您的条件指定为字符串,它将作为表达式生成并针对您的数据运行 我做过的事情的一个例子
var context = new DataContext(ConfigurationManager.ConnectionStrings["c"].ConnectionString);
var statusConditions = "Status = 1";
var results = (IQueryable)context.Contacts.Where(statusConditions);
动态Linq可能是一个选项。将您的条件指定为字符串,它将作为表达式生成并针对您的数据运行 我做过的事情的一个例子
var context = new DataContext(ConfigurationManager.ConnectionStrings["c"].ConnectionString);
var statusConditions = "Status = 1";
var results = (IQueryable)context.Contacts.Where(statusConditions);
我尽量避免使用动态linq,因为linq的要点是强类型访问。使用动态linq是一种解决方案,但它恰恰与linq的目的相反,而且它非常接近于使用ESQL和从sting连接构建查询。无论如何,动态linq有时是实时节省器(特别是在涉及复杂的动态排序时),我成功地将其用于一个大型项目中,使用LINQtoSQL 我通常会定义一些
SearchCriteria
类,比如:
public class SearchCriteria
{
public string Property1 { get; set; }
public int? Property2 { get; set; }
}
和助手查询扩展方法,如:
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;
}
公共静态IQueryable筛选器(此IQueryable查询、SearchCriteria筛选器)
{
if(filter.Property1!=null)query=query.Where(s=>s.Property1==filter.Property1);
if(filter.Property2!=null)query=query.Where(s=>s.Property2==filter.Property2);
返回查询;
}
这不是通用的解决方案。泛型解决方案同样适用于共享某些行为的类的强类型处理
更复杂的解决方案是自己使用谓词生成器和构建表达式树,但构建表达式树只是通过连接字符串来构建ESQL查询的更复杂的方法。我试图尽可能避免动态linq,因为linq的主要点是强类型访问。使用动态linq是一种解决方案,但它恰恰与linq的目的相反,而且它非常接近于使用ESQL和从sting连接构建查询。无论如何,动态linq有时是实时节省器(特别是在涉及复杂的动态排序时),我成功地将其用于一个大型项目中,使用LINQtoSQL 我通常会定义一些
SearchCriteria
类,比如:
public class SearchCriteria
{
public string Property1 { get; set; }
public int? Property2 { get; set; }
}
和助手查询扩展方法,如:
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;
}
公共静态IQueryable筛选器(此IQueryable查询、SearchCriteria筛选器)
{
if(filter.Property1!=null)query=query.Where(s=>s.Property1==filter.Property1);
if(filter.Property2!=null)query=query.Where(s=>s.Property2==filter.Property2);
返回查询;
}
这不是通用的解决方案。泛型解决方案同样适用于共享某些行为的类的强类型处理
更复杂的解决方案是自己使用谓词生成器和构建表达式树,但构建表达式树只是通过连接字符串来构建ESQL查询的更复杂的方法。以下是我的实现:
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);
}
publictget(字符串属性,对象值):其中T是Account
{
//p
var p=表达式参数(typeof(T));
//p、 财产
var propertyExpression=Expression.Property(p,Property);
//p、 属性==值
var equalexpression=Expression.Equal(propertyExpression,Expression.Constant(value));
//p=>p.属性==值
var lambda=表达式.lambda(等式表达式,p);
返回context.Set().SingleOrDefault(lambda);
}
它使用EF5的Set()
方法。如果您使用的是较低版本,则需要实现一种基于
类型获取DbSet的方法
希望有帮助。以下是我的实现:
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);
}
publictget(字符串属性,对象值):其中T是Account
{
//p
var p=表达式参数(typeof(T));
//p、 财产
var propertyExpression=Expression.Property(p,Property);
//p、 属性==值
var equalexpression=Expression.Equal(propertyExpression,Expression.Constant(value));
//p=>p.属性==值
var lambda=表达式.lambda(等式表达式,p);
返回context.Set().SingleOrDefault(lambda);
}
它使用EF5的Set()
方法。如果您使用的是较低版本,则需要实现一种基于
类型获取DbSet的方法
希望能有帮助