【问题标题】:Lambda expression C# Union WhereLambda 表达式 C# Union Where
【发布时间】:2015-12-23 14:43:05
【问题描述】:

我有类的对象

public class Person
    {
        public string Error { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

有些有错误(没有姓名和年龄)有些没有错误(以及姓名和年龄)

Person[] p1 = new Person[] { new Person { Error = "Error1" }, new Person { Name = "Name1", Age = 1 } };



Person[] p2 = p1
                .Where(c => string.IsNullOrEmpty(c.Error))
                .Select(
                    c => new Person { Name = c.Name, Age = c.Age }
                 ).ToArray()
                 Union()
                .Where(d => !string.IsNullOrEmpty(d.Error))
                .Select(
                    d => new Person { Error = d.Error }
                 ).ToArray()

我需要创建第二个数组 p2,在这里我可以从 p1 中选择所有有错误的人员对象,并将同一 p1 中没有错误的所有人员联合起来。

我需要上面代码中的内容,但它不起作用。如何在一个 lambda 子句中编写它?

非常感谢?

【问题讨论】:

  • 这是您想要的语法正确的查询吗? Person[] p2 = p1.Where(c => string.IsNullOrEmpty(c.Error)).Select(c => new Person { Name = c.Name, Age = c.Age }).Union(p1.Where(d => !string.IsNullOrEmpty(d.Error)).Select(d => new Person { Error = d.Error })).ToArray();
  • but it's not working 为什么会这样?
  • 如果您从p1 中选择所有具有Error 和Union 的人,并从p1 中选择所有具有no Error 的人,您将得到p1。 :)
  • 是的,我需要相同的结果p1,这只是一个例子,实际有xml输入

标签: c# asp.net linq lambda


【解决方案1】:

好的,我自己找到了解决方案,应该是这样的:

Person[] p2 = p1
            .Where(c => string.IsNullOrEmpty(c.Error))
            .Select(
                c => new Person { Name = c.Name, Age = c.Age }
             )
            .Union(
            p1.Where(d => !string.IsNullOrEmpty(d.Error))
            .Select(
                d => new Person { Error = d.Error }
             )
             ).ToArray();

对不起,我的回答可能不是很清楚。 谢谢大家的回复。

【讨论】:

    【解决方案2】:

    这将避免出现错误但名称和年龄有值或没有错误但名称和年龄没有值的情况。

    分开:

    var p1Err = p1.Where(p => String.IsNullOrEmpty(p.Error) && !String.IsNullOrEmpty(p.Name) 
                       && !String.IsNullOrEmpty(p.Age));
    var p1NoErr = p1.Where(p => !String.IsNullOrEmpty(p.Error) && String.IsNullOrEmpty(p.Name) 
                        && String.IsNullOrEmpty(p.Age));
    
    var p2 = p1Err.Union(p1NoErr)
                  .ToArray();
    

    综合:

    var p2 = p1.Where(p => String.IsNullOrEmpty(p.Error) && !String.IsNullOrEmpty(p.Name) 
                       && !String.IsNullOrEmpty(p.Age))
               .Union(p1.Where(ip => !String.IsNullOrEmpty(ip.Error) 
                       && String.IsNullOrEmpty(ip.Name) && String.IsNullOrEmpty(ip.Age)))
               .ToArray();
    

    【讨论】:

    • 这实际上不是我需要的,因为我需要在语句中创建新的 Person 对象: c => new Person { Name = c.Name, Age = c.Age } 或 new Person { Error = d.Error } 取决于错误状态,并联合/连接它们
    【解决方案3】:
    p1.Where(c => string.IsNullOrEmpty(c.Error))
                     .Union(p1.Where(d => !string.IsNullOrEmpty(d.Error)))
                    .ToArray()
    

    您需要在.Union 中添加第二个IEnumberable。由于对象已经是您需要的类型,因此无需再次投影。

    虽然在这种情况下有点悬而未决,但结果与p1 相同

    【讨论】:

    • 也许 OP 需要投影,以防范同时具有名称和错误的人(然后他们将失去名称)。
    • 我需要在语句中创建新的 Person 对象:c => new Person { Name = c.Name, Age = c.Age } 或 new Person { Error = d.Error } 取决于错误状态
    • 换句话说,我需要这样: if (string.IsNullOrEmpty(p1[i].Error)) { list.Add(new Person { Name = p[i].Name, Age = p [i].Age }) } else {list.Add(new Person { Error= p[i].Error }} ,所以在 list new Person 对象中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多