我有一张桌子:
tblFildsVal
- id bigint;
- listId bigint;
- listFieldValue bigint;
- parrentId bigint;
然后我有一个表示4个匹配条件的数组(或List):
myArr,该
- listId //参考listId
- rangeType //它有4个vlaue:1)确切2)upper 3)lower 4)之间
- 来自 //较低的值
- 到 //上限值
可以将多个匹配条件链接在一起,以便它对来自 tblFildsVal 的任何记录执行与任何给定条件集的匹配。
例如:
myArr{{1,1,100,Null},{2,2,125,Null},{3,3,Null,175},{4,4,125,175}}
这意味着我想知道每个记录(由parrentId分组)中的任何一个:
(1)listId == 1 && listFieldValue == 100
(2)listId == 2 && listFieldValue > 125
(3)listId == 3 && listFieldValue < 175
(4)listId == 4 && (listFieldValue > 125 && listFieldValue < 175)
(继续休息阵列)
我测试过(全部)&amp; (包含)当我有一维数组时,
var q = from flds in tblFildsVal
group flds by flds.parrentId into gFields
where myArr.All(i => gFields.Select(co => co.listFieldValue).Contains(i))
但在这种情况下我不知道!
答案 0 :(得分:2)
您的问题是您需要实现匹配的逻辑。简单的All或Contains调用将不满足您的数组提供的匹配规则。我在下面实现了一个示例解决方案,它将显示如何编写查询以检查匹配逻辑。
class Program
{
static void Main(string[] args)
{
var myMatchConditions = new int?[][]
{
new int?[] { 1, 1, 100, null },
new int?[] { 2, 2, 125, null },
new int?[] { 3, 3, null, 175 },
new int?[] { 4, 4, 125, 175 }
};
var myData = new MyTableItem[]
{
new MyTableItem { id = 1, listId = 1, listFieldValue = 150, parentId = 1 },
new MyTableItem { id = 2, listId = 1, listFieldValue = 75, parentId = 1 },
new MyTableItem { id = 3, listId = 2, listFieldValue = 150, parentId = 1 },
new MyTableItem { id = 4, listId = 4, listFieldValue = 150, parentId = 1 },
new MyTableItem { id = 5, listId = 5, listFieldValue = 150, parentId = 1 },
};
var matches = from d in myData
where myMatchConditions.Any(cond => (
(cond[0] == d.listId) &&
(cond[1] == 1 ? d.listFieldValue == cond[2] :
(cond[1] == 2 ? d.listFieldValue > cond[2] :
(cond[1] == 3 ? d.listFieldValue < cond[3] :
(cond[1] == 4 ? d.listFieldValue > cond[2] && d.listFieldValue < cond[3] : false)
)
)
)
))
group d by d.parentId into g
select g;
}
class MyTableItem
{
public long id { get; set; }
public long listId { get; set; }
public long listFieldValue { get; set; }
public long parentId { get; set; }
}
}
需要注意的重要事项是对数组进行逻辑检查。在这里,我通过Any调用和一些嵌套的三元运算符完成了它,这不是我推荐的最终解决方案。
如果您可以为匹配条件显式创建一个类,那么可以使其更清晰,然后使用bool MatchesMe(...)
之类的方法来检查每个字段,以便匹配的逻辑可以在视觉上分开来自LINQ声明。
注意:要解决使用实体框架的限制,您需要将匹配条件填充到数据库中的表中,这样您就可以将记录用作匹配逻辑中的对象;或者,更简单的是,您可以将数据库表中的结果作为IEnumerable返回,然后执行与我的示例中相同的匹配逻辑。
我建议创建一个listId
参数列表,这样您只需要根据范围条件撤回需要验证的数据库记录。因此,举例来说,假设您使用List<int> myListIdFilters
中的listId
值设置myMatchConditions
。然后,您将对逻辑检查的第一行进行更改:
var matches = from d in myData.Where(myDataItem => myListIdFilters.Contains(myDataItem.listId)).AsEnumerable()
其余的将保持不变。 AsEnumerable
调用将导致IQueryable
对象被解析,因此逻辑的其余部分将在EF(或LINQ to SQL)上下文之外执行。