带 Contains 的 Linq 查询仅适用于 IQueryable 位于外部变量中
我正在将实体框架与 Linq to Entities 结合使用,尝试从数据库中选择一些数据。当我创建使用 IQueryable
方法的 Linq 查询时,如果我使用外部变量,它只能过滤数据!让我举一些例子。
这段代码工作完美:
var volumes = (from v in work.VolumeAdditiveRepository.All
where v.AdditivesID == AdditivesID
select v.MetricID);
var metrics =
from m in work.MetricRepository.All
where !volumes.Contains(m.ID)
select m;
如果你仔细观察,你会发现我在这段代码中的 where
volumes > 条件。如果我复制此变量的内容并将其粘贴到 metrics
变量中,则会出现下面的代码,它会引发错误:“无法创建“CalculadoraRFS.Models”类型的常量值.Domain.VolumeAditivo'。在此上下文中仅支持原始类型('例如 Int32、String 和 Guid')。”
。
var metrics =
from m in work.MetricRepository.All
where !(from v in work.VolumeAdditiveRepository.All
where v.AdditivesID == AdditivesID
select v.MetricID).Contains(m.ID)
select m;
我的变量替换怎么会导致这样的错误?!我(肯定)做错了什么吗?
谢谢你!
更新:
实际上,正如 @jhamm 指出的那样,我发现存储库模式或 DbContext 似乎是问题所在。下面的代码片段也不起作用:
var query = from m in work._context.Metric
where !(from v in work._context.VolumeAdditive
where v.AdditivesID == AdditivesID
select v.MetricID).Contains(m.ID)
select m;
但是下面的代码片段有效。我刚刚从 UnitOfWork 类中取出了上下文,尽管它的定义非常简单:public CalculadoraRFSContext _context = new CalculadoraRFSContext();
。
var _context = new CalculadoraRFSContext();
var query = from m in _context.Metric
where !(from v in _context.VolumeAdditive
where v.AdditivesID == AdditivesID
select v.MetricID).Contains(m.ID)
select m;
现在我对这些东西真的很困惑!不是应该按预期工作吗?!
I am using Entity Framework with Linq to Entities, trying to select some data from my database. When I create a Linq query that uses the method IQueryable<int>.Contains
, it can only filter the data if I use an external variable! Let me show some example.
This block of code, works perfectly:
var volumes = (from v in work.VolumeAdditiveRepository.All
where v.AdditivesID == AdditivesID
select v.MetricID);
var metrics =
from m in work.MetricRepository.All
where !volumes.Contains(m.ID)
select m;
If you take a good look, you can see I use the variable volumes
inside this snippet, in the where
condition. If I copy the contents of this variable and paste it inside the metrics
variable, leading to the code below, it raises the error: "Unable to create a constant value of type 'CalculadoraRFS.Models.Domain.VolumeAditivo'. Only primitive types ('such as Int32, String, and Guid') are supported in this context."
.
var metrics =
from m in work.MetricRepository.All
where !(from v in work.VolumeAdditiveRepository.All
where v.AdditivesID == AdditivesID
select v.MetricID).Contains(m.ID)
select m;
How can I variable substitution cause such error?! Am I doing (certainly) something wrong?
Thank you!
UPDATE:
Actually, I find out that the Repository Pattern or DbContext seems to be the problem, as @jhamm pointed out. The snippet below doesn't work either:
var query = from m in work._context.Metric
where !(from v in work._context.VolumeAdditive
where v.AdditivesID == AdditivesID
select v.MetricID).Contains(m.ID)
select m;
But the snippet below works. I just took the context out of the UnitOfWork class, though it is very simply defined there: public CalculadoraRFSContext _context = new CalculadoraRFSContext();
.
var _context = new CalculadoraRFSContext();
var query = from m in _context.Metric
where !(from v in _context.VolumeAdditive
where v.AdditivesID == AdditivesID
select v.MetricID).Contains(m.ID)
select m;
Now I'm really confused about this stuff! Wasn't it supposed to work as expected?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我使用 LINQPad 在类似类型的查询上使用我的 EF Database First 模型。组合查询和单独查询都给出相同的正确结果并生成相同的 SQL。以下是有关如何将 LINQPad 与实体框架结合使用的链接。一个区别可能是存储库模式的使用,我没有使用它。我建议使用第一个查询进行测试,看看生成了什么 SQL。运行查询后,LINQPad 有一个 SQL 选项卡,可以通过查看生成的 SQL 来帮助排除正在发生的问题。
如果您在组合 LINQ 语句时仍然遇到问题,那么下一步最好是尝试不使用存储库对象的实体框架对象。如果此查询有效,则您的存储库对象可能有问题。
为了找出问题所在,接下来我将使用 MetricRepository 和 VolumeAdditive EF 对象。
然后我将它们切换为使用带有 VolumeAdditiveRepository 的 Metric EF 对象。
根据生成的 SQL 以及哪些查询有效,我认为这应该可以帮助您指明正确的方向。这是基于消除部分问题直到问题解决为止。然后将它们添加回去,直到它们损坏为止,以指示问题出在哪里。这些步骤应该通过小的增量更改来完成,以最大限度地减少问题空间。
更新:
根据新信息,我们尝试将新信息划分为我们需要回答的新问题。
也许 LINQ 表达式无法弄清楚如何处理 where 子句中的
work._context.VolumeAdditive
。因此,让我们使用以下内容来测试这个理论。这将上下文设置为单个变量,而不是使用 work._context。也许使用 let 语句来定义 MetricID 可以解决此问题。
根据这些测试的结果以及之前 3 个测试/问题的混合和匹配,我们应该越来越接近答案。当我遇到这样的问题时,我会尝试用可验证的答案来问自己问题。基本上,我尝试使用科学方法来缩小问题范围以找到解决方案。
I used LINQPad to use my EF Database First model on a similar type of query. Both the combined and separate queries gave the same correct results and generated the same SQL. Here is a link on how to use LINQPad with Entity Framework. One difference could be the use of the Repository Pattern, I am not using one. I would recommend testing with the first query to see what SQL is generated. After you run a query, LINQPad has a SQL tab that may help troubleshoot what is going on by looking at the generated SQL.
If you are still having trouble with the combined LINQ statement, a good next step would be to try the Entity Framework object without the Repository objects. If this query works, there may be something wrong with your Repository objects.
To find out where the issue lies, I would next use the MetricRepository with the VolumeAdditive EF object.
Then I would switch them to use the Metric EF object with the VolumeAdditiveRepository.
Based on the generated SQL and which queries work, I think this should help point you in the right direction. This is based on removing parts of the problem until it works. Then adding them back in until they break to indicate where the issue is. These steps should be done using small incremental changes to minimize the problem space.
Update:
Based on the new information, lets try to divide the new information into new questions that we need to answer.
Maybe the LINQ expression is not able to figure out what to do with the
work._context.VolumeAdditive
in the where clause. So lets test this theory by using the following. This sets the context to a single variable instead of using work._context.Maybe using a let statement to define the MetricID's could resolve this issue.
Based on the results of these tests and mixing and matching the previous 3 tests/questions, we should be getting closer to the answer. When I come up against issues like this, I try to ask my self questions with verifiable answers. Basically, I try to use the Scientific Method to narrow down the issue to find a resolution.