【问题标题】:Entity Framework 4.1 simple dynamic expression for object.property = valueEntity Framework 4.1 object.property = value 的简单动态表达式
【发布时间】:2011-06-27 23:09:36
【问题描述】:

我知道有一种方法可以使用表达式和 Lambda 来完成此任务,但我很难将它们拼凑在一起。我所需要的只是一个动态查询实体框架 DBSet 对象以查找具有给定名称的属性与值匹配的行的方法。

我的背景:

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

我要写的方法:

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

我宁愿不必使用动态 SQL 来完成此操作,因此无需建议,因为我已经知道这是可能的。我真正需要的是使用表达式和 Lambda 来完成此任务的一些帮助

在此先感谢,我知道它很简短,但应该很容易解释。如果需要更多信息,请发表评论

【问题讨论】:

    标签: linq entity-framework ef-code-first


    【解决方案1】:

    我尽量避免使用动态 linq,因为 linq 的重点是强类型访问。使用动态 linq 是一种解决方案,但它与 linq 的目的完全相反,它非常接近于使用 ESQL 并从 sting 连接构建查询。无论如何,动态 linq 有时可以节省实时时间(尤其是在涉及复杂的动态排序时),我在一个大型项目中成功地使用了它与 Linq-to-Sql。

    我通常做的是定义一些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;
    }
    

    这不是通用的解决方案。同样,通用解决方案是针对共享某些行为的类的某些强类型处理。

    更复杂的解决方案是使用谓词构建器并自己构建表达式树,但同样构建表达式树只是通过连接字符串来构建 ESQL 查询的更复杂的方法。

    【讨论】:

      【解决方案2】:

      这是我的实现:

      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);
      }
      

      它使用 EF 5 的 Set&lt;T&gt;() 方法。如果您使用的是较低版本,则需要实现一种基于 &lt;T&gt; 类型获取 DbSet 的方法。

      希望对你有帮助。

      【讨论】:

        【解决方案3】:

        Dynamic Linq 可能是一种选择。将您的条件指定为字符串,它将构建为表达式并针对您的数据运行;

        我做过的一个例子;

        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

        【讨论】:

          猜你喜欢
          • 2011-11-11
          • 1970-01-01
          • 2011-09-05
          • 1970-01-01
          • 2011-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-23
          相关资源
          最近更新 更多