使这个LINQ投影查询更好

时间:2012-03-15 21:21:22

标签: c# linq

假设我有一个像这样定义的域类:

public class MyDomainItem
{
    public string PropertyA {get;set;}
    public string PropertyB {get;set;}
    public string ItemStatus {get;set;}
    public ClassA ObjectA {get;set;}
    public ClassB ObjectB {get;set;}
}

然后我有一个看起来像这样的LINQ查询:

var mylist = from a in someList 
              join b in someOtherList on a.Id equals b.Id
              select new MyDomainItem
              {
                  PropertyA = a.SomeProperty,
                  PropertyB = b.SomeOtherProperty,
                  ObjectA = a,
                  ObjectB = b
              }

根据我所知,我可以通过以下方式解决ItemStatus

foreach(var i in mylist)
{
    if (i.ObjectA.YetAnotherProperty == "some criteria")
    {
        if (i.ObjectA.NestedObject.NestedProperty == "price is missing")
        {
            i.ItemStatus = "bad - category 1";
        }
        else
        {
            i.ItemStatus = "bad - category 2";
        }
    }
    else
    {
        i.ItemStatus = "good";
    }
}

或者通过调用函数,在LINQ查询中解析:

var mylist = from a in someList 
              join b in someOtherList on a.Id equals b.Id
              select new MyDomainItem
              {
                  PropertyA = a.SomeProperty,
                  PropertyB = b.SomeOtherProperty,
                  ObjectA = a,
                  ObjectB = b,
                  ItemStatus = ResolveStatus(a)
              }

在我的脑海里,我只是一直在说必须有更好的方法。我真正喜欢做的事情大致如下:

var mylist = from a in someList 
              join b in someOtherList on a.Id equals b.Id
              select new MyDomainItem
              {
                  PropertyA = a.SomeProperty,
                  PropertyB = b.SomeOtherProperty,
                  ObjectA = a,
                  ObjectB = b,
                  ItemStatus = ()=>
                  {
                      if (a.ObjectA.YetAnotherProperty == "some criteria")
                      {
                          if (a.ObjectA.NestedObject.NestedProperty == 
                              "price is missing")
                          {
                              return "bad - category 1";
                          }
                          else
                          {
                              return "bad - category 2";
                          }
                      }
                      else
                      {
                          return "good";
                       }
                  }
              }

我能做些什么吗?

提前致谢... !!!

2 个答案:

答案 0 :(得分:1)

这样的事情怎么样?

select new MyDomainItem
{
    PropertyA = a.SomeProperty,
    PropertyB = b.SomeOtherProperty,
    ObjectA = a,
    ObjectB = b,
    ItemStatus = (a.YetAnotherProperty == "some criteria")
                     ? (a.NestedObject.NestedProperty == "price is missing"
                         ? "bad - category 1"
                         : "bad - category 2")
                     : "good";

虽然我建议使用为您进行此评估的属性扩展ObjectA,但它在LINQ查询中看起来并不好看。如果您没有源,可以使用扩展方法

string GetItemStatus(this ObjectA item) {
    if (item.YetAnotherProperty != "some criteria") {
        return "good";
    }
    if (item.NestedObject.NestedProperty == "price is missing") {
        return "bad - category 1";
    }
    return "bad - category 2";
}

答案 1 :(得分:1)

为什么不创建一个接受两个属性和两个对象的MyDomainItem构造函数,并设置状态?它将使MyDomainItem成为一个更健壮的类(状态有效性将不依赖于调用者的善意),并且还将解决您的样式问题。