.net 用EF查询平面表结构
我使用的是EF(4.4),有一个带有.net 用EF查询平面表结构,.net,entity-framework,entity-framework-4,.net,Entity Framework,Entity Framework 4,我使用的是EF(4.4),有一个带有N列的平面表,列名为Value1值n 基于另一列(ValueIndex),我需要获取N值为ValueN-1、ValueN和ValueN+1 例如,如果ValueIndex是3,我需要获取Value2、Value3和Value4 为了简单起见,假设ValueIndex没有边界问题,即不是1或N,并且我有7列Value列 如果这是在记忆中,我会(也可能会)做这样的事情: table.Select(t => new { ValueIndex = t
N
列的平面表,列名为Value1
<代码>值n
基于另一列(ValueIndex
),我需要获取N
值为ValueN-1
、ValueN
和ValueN+1
例如,如果ValueIndex
是3
,我需要获取Value2
、Value3
和Value4
为了简单起见,假设ValueIndex
没有边界问题,即不是1
或N
,并且我有7列Value
列
如果这是在记忆中,我会(也可能会)做这样的事情:
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]
}
);
不幸的是,由于数组索引不受支持,这在EF中不起作用
作为一种解决方法,我尝试用索引器select替换数组索引:
.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(),
}
);
但不幸的是,这也不受支持(LINQ to Entities不识别Where
方法中的t.Values
变量)
我并不特别希望在我的代码中有一个巨大的switch语句:
tables.Select(t =>
new[] {
t.ValueIndex == 2 ?
new[] {
t.Value1,
t.Value2,
t.Value3,
}
: t.ValueIndex == 3 ?
new[] {
t.Value2,
t.Value3,
t.Value4,
}
: // Etc..
}
);
那么,在使用EF(即转换为SQL)之后,有没有其他方法可以实现我所追求的查询,而不是使用大规模的转换/案例?实体框架(以及许多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);
}
公共类三元组
{
公共字符串Item1{get;set;}
公共字符串Item2{get;set;}
公共字符串Item3{get;set;}
}
公共静态IQueryable GetTriplets(IQueryable源)
{
兰姆达变种=
表情
.Lambda(表达式.MemberInit(
表达式.New(typeof(Triplet)),
CreateMemberBind(-1),
CreateMemberBind(0),
CreateMemberBind(1));
返回源。选择(lambda);
}
我认为这和我想象的一样好。谢谢你的回答。