我可以在单个LINQ查询中完成此查询吗?

时间:2013-07-06 20:52:26

标签: c# linq linq-to-sql

我有一个复杂的情况,我正在努力解决,但我的SQL和LINQ的技能最好是温和的,我不知道如何实现这一点。我可以通过多个查询来完成,但我很想知道我是否可以用一个查询。

我在SQL中有一个Pricing表。我关注的三个字段是SearchCodeGUIDLocationGUIDClientGUID。位置和客户端都可以为空。

执行查询时,我有一个SearchGUID,一个StateGUID,一个CountyGUID和一个ClientGUID。以下是我想要执行的查询。对于所有这些,我想要SearchGUID = SearchGUID。操作顺序如下:

首先,我想检查客户是否有县的价格 - ClientGUID = ClientGUIDLocationGUID = CountyGUID

如果不存在,我想看看是否有该县的记录 - LocationGUID = CountyGUID

如果不存在,我想看看是否有该状态的记录 - LocationGUID = StateGUID

最后,如果不存在,我只想要LocationGUIDClientGUID为空且SearchGUID匹配的记录。

2 个答案:

答案 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());