这段代码完美无缺:
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;
现在我真的很困惑这个东西!它不应该按预期工作吗?!
解决方法
如果您仍然遇到组合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个测试/问题,我们应该更接近答案.当我遇到这样的问题时,我试着用可验证的答案问我的自我问题.基本上,我尝试使用科学方法来缩小问题范围以找到解决方案.