【问题标题】:Can't get Dynamic Linq to work无法让 Dynamic Linq 工作
【发布时间】:2017-03-24 01:26:35
【问题描述】:

我正在尝试使用 Dynamic Linq 库来查询我的实体框架数据源。我已将正确的包添加到我的项目中,并使用了以下语法

 var salesEntities = dashboardEntity.FactSales.Where(d => d.DateKey >= startDate).Where(d => d.DateKey <= endDate)
                                    .Where(c => c.CompanyID == companyID)
                                    .Where("StoreID==@0",1)
                                    .ToList();

我也试过

 .Where("StoreID=1")

根据我在 ScottGu 博客文章中找到的示例,大多数动态查询 SO 问题似乎都暗示了这一点。谁能帮我看看我缺少什么来完成这项工作?

它不会产生错误,只是根本无法返回任何数据。

【问题讨论】:

  • 我刚刚创建了一个简单的测试样本,我需要使用Dynamic Linq的原因是因为用户需要能够选择1个或多个商店在运行时动态查看,这就是为什么.Where StoreID 的 () 与其他的是分开的
  • 我上次检查linq时,它不支持那种语法。您可能需要构建自己的谓词...谓词基本上用于创建动态查询...将多过滤器搜索视为可能的场景。这是一个很好的例子:c-sharpcorner.com/UploadFile/c42694/…... C# 6.0 已经有一个PredicateBuilder,你可能想检查一下。
  • 你可以试试.Where(s =&gt; s.StoreID == 1) 吗?它是否返回数据?
  • Dynamic LINQ的文档源代码可以在here找到。
  • IQueryable&lt;T&gt; 上的@DavidEspino LINQ 方法采用可以通过两种方式构造的表达式:编译器生成 -- .Where(x =&gt; x.StoreID = 1),并在运行时使用 System.Linq.Expressions.Expression 类中的静态方法构建,例如如.ConstantMakeMemberAccessParameterDynamic LINQ library 允许第三个选项——字符串然后被转换成表达式。

标签: c# entity-framework linq dynamic-linq


【解决方案1】:

TL;DR

您确定为此需要动态 LINQ 吗?

List<int> storeIDs = new List<int>() {1,2,3};
var salesEntities = dashboardEntity.FactSales
    .Where(d => d.DateKey >= startDate)
    .Where(d => d.DateKey <= endDate)
    .Where(c => c.CompanyID == companyID)
    .Where(c => storeIDs.Contains(c.StoreID))
    .ToList();

加长版

LINQ 允许编译器生成表达式:

IQueryable<FactSales> qry;
qry = qry.Where(x => x.DateKey >= startDate);

如果表达式需要在运行时更改,可以使用System.Linq.Expressions.Expression class中的静态方法构建表达式:

//using static System.Linq.Expressions.Expression;

//x
var parameter = Parameter(typeof(FactSale));

//x.DateKey
var dateKey = MakeMemberAccess(parameter, typeof(FactSales).GetProperty("DateKey"));

//(the value in startDate, as if it had been written in)
var startDateConst = Constant(startDate);

//x.DateKey >= (value of startDate)
var comparison = GreaterThanOrEqual(dateKey, startDateConst);

//x => x.DateKey >= (value of startDate)
var lmbd = Lambda<Func<FactSale,bool>>(comparison, new [] {prm});

//pass the expression into the Queryable.Where method
qry = qry.Where(lmbd);

Dynamic LINQ 库(可以找到其最新版本here)允许使用字符串生成表达式:

IQueryable<FactSales> qry;
qry = qry.Where("DateKey >= @0", startDate);

当表达式在编译时未知时,动态 LINQ 非常有用,但在这种情况下,表达式在编译时是已知的(在这种情况下,使用 List&lt;T&gt;.Contains method。因此我看不出有任何理由在此处使用动态 LINQ。

注意我仍然不知道为什么这不起作用:

var qry = dashboardEntity.FactSales.Where("StoreID = 1");

【讨论】:

  • 谢谢,我从来不知道 .Contains 的功能,这对我很有帮助!
  • @NateGreene 我已经扩展了我的答案。
【解决方案2】:

如果你解决了这个问题,我想知道,但我刚刚注意到你对我的评论的回复。

我认为您在比较 StoreID 时缺少的是 = 而不是 ==

var salesEntities = dashboardEntity.FactSales.Where(d => d.DateKey >= startDate).Where(d => d.DateKey <= endDate)
                                .Where(c => c.CompanyID == companyID)
                                .Where("StoreID = @0",1)
                                .ToList();

【讨论】:

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