Linq用大括号查询匿名动作/函数体

时间:2012-04-04 06:13:43

标签: c# linq linq-to-objects

我有这样的实体:

public class Parent: AllDependant
{
    /*Properties goes here*/
}

public class Children: AllDependant
{
    /*Properties goes here*/
}

然后我有allDependants变量,其类型为List<AllDependant>,这将保留一些父母和子女的权利。

稍后,我想从中选择并执行以下操作:

var selectedDependantInfos = allDependants
        .Select(dependant =>
        {
            if (dependant is Parent)
            {
                var parent = dependant as Parent;
                return new { Name = parent.Name, SomeSpecialInfo = parent.ParentInfo };
            }
            else
            {
                var child = dependant as Children;
                return new { Name = child.Name, SomeSpecialInfo = child.ChildInfo }
            }
        });

请注意,child和parent的特定属性要求我将属性转换为获取UI显示的新模型,而不是实体关注。我不能把特殊属性放在AllDependant基类中,因为我需要在很多文件上重构属性名,包括* .ascx这很麻烦。不过它是通过使用上面的Linq Select扩展方法完成的,但我只想到这个:

问题:如何在Linq查询中执行相同的操作?

这会在select关键字和花括号上显示错误:

var selectedDependantInfos = from dependant in allDependants
                            select
                            {
                                /* the same if statement goes here */
                            }

3 个答案:

答案 0 :(得分:3)

您将使用条件运算符并获得类似

的内容
  from dependant in allDependants             
  select dependant is Parent 
         ? new { Name = (dependant as Parent).Name,  /* Parent fields */ }
         : new { Name = (dependant as Children).Name, /* Child fields */ }

但是你看,这并不是一个很大的进步。没有方便的地方进行类型转换。

更好的选择似乎是将Name和SpecialInfo属性移动到基类(AllDependant或特殊中间类)。

答案 1 :(得分:2)

另一种选择是:

var parents = allDependants.OfType<Parent>.Select(p => new { Name =  p.Name, .... };
var children = allDependants.OfType<Children>.Select(c => new { Name =  c.Name, .... };

var combined = parents.Concat(children);

这种方法的缺点是addDependants会被迭代两次。

答案 2 :(得分:0)

使用Reflection的另一种方式

var selectedDependantInfos = from p in allDependants
                         let key = p is Parent ? "ParentInfo" : "ChildInfo"
                         select new { 
                             Name = p.GetType().GetProperty("Name").GetValue(p, null).ToString(), 
                             SomeSpecialInfo = p.GetType().GetProperty(key).GetValue(p, null).ToString() 
                         };