我有一个复杂的情况,我正在努力解决,但我的SQL和LINQ的技能最好是温和的,我不知道如何实现这一点。我可以通过多个查询来完成,但我很想知道我是否可以用一个查询。
我在SQL中有一个Pricing
表。我关注的三个字段是SearchCodeGUID
,LocationGUID
和ClientGUID
。位置和客户端都可以为空。
执行查询时,我有一个SearchGUID,一个StateGUID,一个CountyGUID和一个ClientGUID。以下是我想要执行的查询。对于所有这些,我想要SearchGUID = SearchGUID
。操作顺序如下:
首先,我想检查客户是否有县的价格 - ClientGUID = ClientGUID
和LocationGUID = CountyGUID
如果不存在,我想看看是否有该县的记录 - LocationGUID = CountyGUID
如果不存在,我想看看是否有该状态的记录 - LocationGUID = StateGUID
最后,如果不存在,我只想要LocationGUID
和ClientGUID
为空且SearchGUID
匹配的记录。
答案 0 :(得分:1)
一种方法是使用OrderBy:
IQueryable<Pricing> table = ...
var matches = table.Where(p => p.SearchGUID = searchGUID);
var result = matches.Select(p => new
{
pricing = p
// 0 score if client & county match
score = p.ClientGUID == clientGUID && p.LocationGUID == countyGUID
? 0
// 1 score if just county match
: p.LocationGUID == countyGUID
? 1
// 2 score if just state match
: p.LocationGUID == stateGUID
? 2
// 3 score if client & location are null
: p.ClientGUID == null && p.LocationGUID == null
? 3
// 4 score if it missed all conditions
: 4
})
.Where(t => t.score < 4) // eliminate mismatches
.OrderBy(t => t.score) // put low scores first
.Select(t => t.pricing) // if we want to read just the pricing entity, select it
.FirstOrDefault(); // take the first match, or null if no match was found
答案 1 :(得分:1)
我喜欢Chase的答案,但我想我会发布一个更传统的答案。鉴于对大量数据的惰性列表,这可能更快......但我没有声明,因为我对您的实际数据模型一无所知。
var idMatch = Pricing.Select(p => p.SearchCodeGUID == SearchGUID);
var countyMatch = idMatch.Select(p => p.LocationGUID == CountyGUID);
if (countryMatch.Any()) // match one of two first cases
{
var clientToo = countyMatch.Select(p => p.ClientGUID == ClientGUID)
.FristOrDefault();
if (clientToo != null)
return(clientToo);
else
return(countyMatch.First());
}
var stateMatch = idMatch.Select(p => p.LocationGUID == stateGUID)
.FirstOrDefault();
if (stateMatch != null)
return(stateMatch);
return(idMatch.Select(p => (LocationGUID == null) && (ClientGUID == null))
.FirstOrDefault());