c# – 带有包含的Linq查询仅适用于IQueryable在外部变量中
我正在使用实体框架与
Linq to Entities,尝试从我的数据库中选择一些数据.当我创建一个使用方法IQueryable< int> .Contains的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片段中使用此片段中的变量卷.如果我复制此变量的内容并将其粘贴到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; 我如何变量替换导致这样的错误?!我(肯定)做错了吗? 更新: 实际上,我发现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; 但下面的代码段可行.我刚从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; 现在我真的很困惑这个东西!它不应该按预期工作吗?! 解决方法
我使用
LINQPad在类似类型的查询上使用我的EF Database First模型.组合查询和单独查询都给出了相同的正确结果并生成了相同的SQL.这是一个关于如何
use LINQPad with 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; 为了找出问题所在,接下来我将使用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; 然后我将它们切换为使用带有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; 根据生成的SQL和哪些查询有效,我认为这应该有助于指明您正确的方向.这是基于删除部分问题直到它工作.然后将它们重新添加,直到它们断开以指示问题所在.应使用小的增量更改来完成这些步骤,以最大限度地减少问题空间. 更新: 根据新信息,让我们尝试将新信息分成我们需要回答的新问题. 也许LINQ表达式无法弄清楚如何处理where子句中的work._context.VolumeAdditive.因此,让我们使用以下方法测试这个理论.这将上下文设置为单个变量,而不是使用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; 也许使用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; 根据这些测试的结果,混合和匹配前面的3个测试/问题,我们应该更接近答案.当我遇到这样的问题时,我试着用可验证的答案问我的自我问题.基本上,我尝试使用科学方法来缩小问题范围以找到解决方案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |