我今天已经工作了好几个小时,觉得有一种简单的方法可以做到这一点,但除了蛮力外,我无法通过任何其他方式使其工作。
我的应用程序中有一个实体,用作两个对象之间的映射,基于5个过滤器。目标是找到与过滤器最具体匹配的记录。
现在,我手动强制执行2 ^ 5个查询以获取最具体的行,但感觉必须有一个更简单的方法来执行此操作。
这里唯一的问题是数据库中可能没有匹配特定的过滤器(或所有),在这种情况下我想选择NULL记录。
下面我有一个我尴尬的暴力查询的摘录 - 我首先要尝试匹配所有5个过滤器,然后是4个匹配的排列,然后是3个,然后是2个,然后是1个,最后是所有Null。
incList.FirstOrDefault(x =>
x.Filter1 == filter1Parameter && x.Filter2 == filter2Parameter && x.Filter3 == filter3Parameter && x.Filter4 == filter4Parameter && x.Filter5 == filter5Parameter
|| x.Filter1 == null && x.Filter2 == filter2Parameter && x.Filter3 == filter3Parameter && x.Filter4 == filter4Parameter && x.Filter5 == filter5Parameter
|| x.Filter1 == filter1Parameter && x.Filter2 == null && x.Filter3 == filter3Parameter && x.Filter4 == filter4Parameter && x.Filter5 == filter5Parameter
|| x.Filter1 == filter1Parameter && x.Filter2 == filter2Parameter && x.Filter3 == null && x.Filter4 == filter4Parameter && x.Filter5 == filter5Parameter
|| x.Filter1 == filter1Parameter && x.Filter2 == filter2Parameter && x.Filter3 == filter3Parameter && x.Filter4 == null && x.Filter5 == filter5Parameter
|| x.Filter1 == filter1Parameter && x.Filter2 == filter2Parameter && x.Filter3 == filter3Parameter && x.Filter4 == filter4Parameter && x.Filter5 == null
我原本以为我可以有一个简单的语句,如果存在则可以独立获取值,如果不存在则获取null
incList.FirstOrDefault(x => (x.Filter1 == filter1Parameter || x.Filter1 == null) &&
(x.Filter2 == filter2Parameter || x.Filter2 == null) &&
(x.Filter3 == filter3Parameter || x.Filter3 == null) &&
(x.Filter4 == filter4Parameter || x.Filter4 == null) &&
(x.Filter5 == filter5Parameter || x.Filter5 == null));
但那没用。
任何指针都会受到赞赏。
答案 0 :(得分:0)
我仍在努力了解要求的全部范围。
但是,您是否已经探索过在单独的类中抽象此Func或Func(s)。这个单独的类或类将像策略一样运作。仅负责基于某个谓词过滤集合的内容。
如果这看起来不是一条好路线,那么考虑编写自己的实现IEqualityComparer。这将允许您确定使这些对象相等的原因。
答案 1 :(得分:0)
您可以引入类似“健身功能”的内容,然后选择具有最大适合值的项目
var bestMatch = incList.Select(x => new
{
item = x,
fit =
(x.Filter1 == null
? 1
: (x.Filter1 == filter1Parameter ? 2 : 0)) *
(x.Filter2 == null
? 1
: (x.Filter2 == filter2Parameter ? 2 : 0)) // and so on
})
.OrderByDescending(x => x.fit)
.FirstOrDefault(x => x.fit > 0)?.item;