tyr*_*ron 7 c# asp.net linq-to-entities entity-framework iqueryable
我正在使用实体框架与Linq to Entities,尝试从我的数据库中选择一些数据.当我创建使用该方法的Linq查询时,IQueryable<int>.Contains如果我使用外部变量,它只能过滤数据!让我举一些例子.
这段代码完美无缺:
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;
Run Code Online (Sandbox Code Playgroud)
如果您仔细观察,您可以看到我volumes在此片段中使用变量where.如果我复制此变量的内容并将其粘贴到metrics变量中,导致下面的代码,则会引发错误:"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;
Run Code Online (Sandbox Code Playgroud)
我如何变量替换导致这样的错误?!我(肯定)做错了吗?
谢谢!
更新:
实际上,我发现Repository Pattern或DbContext似乎是问题所在,正如@jhamm指出的那样.下面的代码段不起作用:
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;
Run Code Online (Sandbox Code Playgroud)
但下面的代码段可行.我刚从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;
Run Code Online (Sandbox Code Playgroud)
现在我真的很困惑这个东西!它不应该按预期工作吗?!
我使用LINQPad在类似类型的查询上使用我的EF Database First模型.组合和单独的查询都给出了相同的正确结果并生成了相同的SQL.以下是有关如何使用LINQPad和Entity Framework的链接.一个区别可能是使用存储库模式,我没有使用它.我建议使用第一个查询进行测试,以查看生成的SQL.运行查询后,LINQPad有一个SQL选项卡,可以通过查看生成的SQL来帮助解决发生的问题.
如果您仍然遇到组合LINQ语句的问题,那么下一步就是尝试没有Repository对象的Entity Framework对象.如果此查询有效,则可能存在Repository对象的错误.
// Guessing that Metric and VolumeAdditive are the EF Entities
// LINQPad database dropdown sets the context so they were not set it in these samples
var metrics =
from m in Metric
where !(from v in VolumeAdditive
where v.AdditivesID == AdditivesID
select v.MetricID).Contains(m.ID)
select m;
Run Code Online (Sandbox Code Playgroud)
为了找出问题所在,接下来我将使用MetricRepository和VolumeAdditive EF对象.
var metrics =
from m in work.MetricRepository.All
where !(from v in VolumeAdditive
where v.AdditivesID == AdditivesID
select v.MetricID).Contains(m.ID)
select m;
Run Code Online (Sandbox Code Playgroud)
然后我将它们切换为使用带有VolumeAdditiveRepository的Metric EF对象.
var metrics =
from m in Metric
where !(from v in work.VolumeAdditiveRepository.All
where v.AdditivesID == AdditivesID
select v.MetricID).Contains(m.ID)
select m;
Run Code Online (Sandbox Code Playgroud)
基于生成的SQL以及查询的工作原理,我认为这有助于指明您正确的方向.这是基于删除部分问题直到它工作.然后将它们重新添加,直到它们断开以指示问题所在.应使用小的增量更改来完成这些步骤,以最大限度地减少问题空间.
更新:
根据新信息,我们尝试将新信息划分为我们需要回答的新问题.
也许LINQ表达式无法弄清楚如何处理work._context.VolumeAdditivewhere子句.因此,让我们使用以下方法测试这个理论.这将上下文设置为单个变量,而不是使用work._context.
var _context = work._context;
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;
Run Code Online (Sandbox Code Playgroud)
也许使用let语句来定义MetricID可以解决这个问题.
var metrics =
from m in work.MetricRepository.All
let volumes = from v in work.VolumeAdditiveRepository.All
where v.AdditivesID == AdditivesID
select v.MetricID
where !volumes.Contains(m.ID)
select m;
Run Code Online (Sandbox Code Playgroud)
根据这些测试的结果,混合并匹配前面的3个测试/问题,我们应该更接近答案.当我遇到这样的问题时,我试着用可验证的答案问我的自我问题.基本上,我尝试使用科学方法缩小问题范围以找到解决方案.
| 归档时间: |
|
| 查看次数: |
10675 次 |
| 最近记录: |