我正在使用EF(4.4),并且有一个名为N
的{{1}}列的平面表... Value1
。
根据另一列(ValueN
),我需要抓取ValueIndex
N
,ValueN-1
和ValueN
例如,如果ValueN+1
为ValueIndex
,我需要3
,Value2
和Value3
。
为简单起见,假设Value4
没有边界问题,即不是ValueIndex
或1
,而且我有7 N
列。
如果这是在记忆中我会做(也可能会做)这样的事情:
Value
不幸的是,由于数组索引不受支持,这在EF中不起作用。
作为一种解决方法,我尝试用索引器选择替换数组索引:
table.Select(t =>
new {
ValueIndex = t.ValueIndex,
Values = new[] {
Value1, Value2, Value3, Value4, Value5, Value6, Value7
}
})
.Select(t =>
new[] {
Values[ValueIndex-1], Values[ValueIndex], Values[ValueIndex+1]
}
);
但遗憾的是,它也不受支持(LINQ to Entities无法识别.Select(t =>
new[] {
t.Values.Where((v, i) => i == t.ValueIndex-1).First(),
t.Values.Where((v, i) => i == t.ValueIndex).First(),
t.Values.Where((v, i) => i == t.ValueIndex+1).First(),
}
);
变量上的Where
方法。
我并不特别想在我的代码中使用巨大的switch语句:
t.Values
那么有什么方法可以实现我在使用EF(即可转换为SQL)之后以非常大的交换机/案例的方式进行查询?
答案 0 :(得分:1)
实体框架(和许多ORM)是为关系数据库设计的。在其他情况下(文档存储或键值存储),它们往往会崩溃......
也就是说,如果你的实体框架仍然是正确的工具,那么考虑一下如何在SQL中处理它...这听起来像是对我的支点。
SELECT CASE WHEN ValueIndex = 1 THEN Value0 WHEN ValueIndex = 2 THEN Value1...... END,
CASE WHEN ValueIndex = 1 THEN Value1 WHEN ValueIndex = 2 THEN Value2.... END,
CASE When ValueIndex = 1 THEN Value2 WHEN ValueIndex = 2 THEN Value3..... END
FROM ....
所以......你能在LINQ中构建它吗?当然...
from t in in table
select new
{
ValueIndex = t.ValueIndex,
First = t.ValueIndex == 1 ? t.Value0 : (t.ValueIndex == 2 ? t.Value1 : ....),
Second = t.ValueIndex == 1 ? t.Value1 : (t.ValueIndex == 2 ? t.Value2 : ....),
Third = t.ValueIndex == 1 ? t.Value2 : (t.ValueIndex == 2 ? t.Value3 : ....)
}
虽然有点难看......
如果你想让它可持续发展,你可以很容易地动态地构建表达式树。
所以你可以拥有像
这样的东西public class Triplet
{
public string Item1 { get; set; }
public string Item2 { get; set; }
public string Item3 { get; set; }
}
public static IQueryable<Triplet> GetTriplets(IQueryable<TableRow> source)
{
var lambda =
Expression
.Lambda<Func<TableRow, Triplet>>(Expression.MemberInit(
Expression.New(typeof (Triplet)),
CreateMemberBind(-1),
CreateMemberBind(0),
CreateMemberBind(1)));
return source.Select(lambda);
}