我正在尝试实现c#linq表达式,该表达式将允许我根据年份和月份提取数据。该错误在上下文的where方法中引发。
我目前收到错误消息
System.NotSupportedException: 'Unable to create a constant value of type 'System.Tuple`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. Only primitive types or enumeration types are supported in this context.'
Linq表达式
var periodTuples = period.ToList() // gives you List<KeyValuePair<int, int[]>>
.SelectMany(kvp =>
kvp.Value.Select(it2 => Tuple.Create(kvp.Key, it2))).ToHashSet(); // to optimize .Contains()
benchmark1Returns = GetViewService<MV_INDEX_PERFORMANCE>()
.Where(x => x.Mtd != null && x.IndexId == benchMark1 && periodTuples.Contains(Tuple.Create(x.PriceDate.Year, x.PriceDate.Month))).Select(x => x.Mtd);
Where方法在我的上下文中定义
public IEnumerable<T> Where(Expression<Func<T, bool>> predicate)
{
try
{
using (new TimedLogger(_perfLogger, GetCompletedText("Where")))
{
return Authorize(_repo.Where(predicate).ToList(), AuthAccessLevel.Read);
}
}
catch (Exception ex)
{
_logger.Error(ex);
throw;
}
}
答案 0 :(得分:1)
尝试加入吗?
var benchmark1Returns = GetViewService<MV_INDEX_PERFORMANCE>()
.Where(x => x.Mtd != null && x.IndexId == benchMark1)
.Join(periodTuples,
b1r => new { x = b1r.PriceDate.Year, y = b1r.PriceDate.Month },
tuple => new { x = tuple.Item1, y = tuple.Item2 },
(b, t) => b.Mtd);
答案 1 :(得分:1)
EF6不支持(无法转换为SQL)Tuple.Create
(和Tuple<>
构造函数),内存中集合联接,Contains
非基本类型和许多其他类型的内存中集合其他人。
您这种情况下的解决方案是用原始类型表达式替换(int year,int month)对:
int period = 12 * year + (month - 1)
并将其用于过滤,例如
var periods = period.ToList() // gives you List<KeyValuePair<int, int[]>>
.SelectMany(kvp => kvp.Value, (year, month) => 12 * year + (month - 1));
然后在LINQ查询中
periods.Contains(12 * x.PriceDate.Year + (x.PriceDate.Month - 1))
请注意,在LINQ to Entities中,查询periods
不必为HashSet<int>
(或List<int>
等)-IEnumerable<int>
就足够了,因为它将在本地求值一次并转换为SQL IN (val1, val2, ..., valN)
标准。