【问题标题】:Populate List Where Contains values (or objects) from another list填充列表,其中包含来自另一个列表的值(或对象)
【发布时间】:2012-07-09 14:37:19
【问题描述】:

我想填充一个列表,其中对象中的值位于我已经填充的另一个列表中。请看下面:

//Populate first object
List<Object1> listObject1 = da.dbsetObject1.Where(p=>p.ID.Equals(SomeID)).ToList();

//Populate second object - what I want to do but can't figure out
List<Object2> listObject2 = da.dbsetObject2.Where(p=>p.ID.Contains(listObject1.Object1ID)).ToList();

我知道 contains 不起作用,但我想基本上用具有匹配 Object1ID 的所有值填充 listObject2。在 sql 表中,这将是一个外键关系。

【问题讨论】:

标签: c# .net sql linq entity-framework


【解决方案1】:

然后join这两个列表:

var results = from l2 in listObject2
              join l1 in listObject1 on l2.ID equals l1.Object1ID
              select new{anonymous type}

【讨论】:

  • 看来我需要先填充 listObject2 然后将我想要的结果填充到第三个变量中。对吗?
  • @Bryce,是的,或者您可以直接将两个da.dbsetObject1da.dbsetObject2 与您要添加的条件连接起来,以限制您在这两个列表中的选择。
  • 我唯一担心的是,随着 Object2 的表变大,我正在填充一个大对象/SQL 响应时间变慢。没有办法像在 sql 中那样将 Object1IDs 包含为 WHERE 条件?我正在考虑多次从 sql server 带回大型结果集然后在应用程序服务器上处理它们的性能,以及让 sql server 最初带回较小的结果集可能有多慢。
【解决方案2】:

编辑

基于 cmets 中的更新信息

var lstObject1 = listObject1.Select(item -> item.ObjectId).ToArray();  
List<Object2> listObject2 = da.dbsetObject2.Where(p=> lstObject1.Contains(p.ObjectId)).ToList();

原创

问题从代码中看不清楚

假设你不能在 List 中使用 p.ID,结果查询是

  List<Object2> listObject2 = da.dbsetObject2.Where(p=> listObject1.Contains(p.ID)).ToList();

【讨论】:

  • 这似乎是我想要的。但是,我需要在我的代码中对其进行测试。我必须做的唯一改变是我通过 p.Object1 而不是使用 p.ID
  • 我在 listObject1 上遇到错误“匹配的最佳重载方法有一些无效参数”
  • p.Object1 的数据类型不是 Object1 吗?在这种情况下,将需要 Cast 运算符。在问题中发布 Object1 的数据类型。
  • Object1 和 Object2 是类。它们包含整数、字符串等。它们应该加入 Object1.Object1ID == Object2.Object1ID。
  • 这个选项效果很好,实际上比我发现的 .Include 效果更好。非常感谢。
【解决方案3】:

试试这样的。

//Populate first object
List<Object1> listObject1 = da.dbsetObject1.Where(p => p.ID.Equals(SomeID)).ToList();

//Populate second object - what I want to do but can't figure out
List<Object2> listObject2 = da.dbsetObject2.Where(p => listObject1.Any(q => q.ID == p.foreignID)).ToList();

更新

void SomeMethod(){
      var arr = new Object1[]{
            new Object1{Name="n1",ID=1},
            new Object1{Name="n2",ID=2},
            new Object1{Name="n3",ID=3},
            new Object1{Name="n4",ID=4}
        };

        var arr2 = new Object2[]{
            new Object2{Name="o1", Ref=1},
            new Object2{Name="o2", Ref=2},
            new Object2{Name="o3", Ref=1},
            new Object2{Name="o4", Ref=2},
            new Object2{Name="o5", Ref=5},
            new Object2{Name="o6", Ref=3},
            new Object2{Name="o7", Ref=5}
        };

        List<Object1> listObject1 = arr.Where(p => p.ID == 1 || p.ID == 2).ToList();

        List<Object2> listObject2 = arr2.Where(p =>listObject1.Any(q => p.Ref == q.ID)).ToList();
}

    class Object1
    {
        public string Name;
        public int ID;
    }
    class Object2
    {
        public string Name;
        public int Ref;
    }

【讨论】:

  • 我尝试了这种技术,但 listobject2 中的 q 出错了。它错误说无法将 lambda 表达式转换为 Object1 类型,因为它不是委托类型
  • @Bryce 抱歉,我忘记使用 Any 扩展方法而不是 Contains,因为 Contains 不支持 lambda。我将用一个完整的工作示例更新我的答案。
【解决方案4】:

我找到了我想要做的最好的方法。这是我需要的代码:

var NewObject = da.dbsetObject1.Include("listObject2").ToList();

然后我可以使用 NewObject 作为一个列表,当我需要一个与特定 Object1 值关联的 Object2 值时,我可以抓取它。

以下是课程:

public class Object1
{
    [Key]
    public int Object1ID { get; set; }
    .....
    public int Object2ID { get; set; }
    public List<Object2> listObject2 { get; set; }
}

public class Object2
{
    [Key]
    public int Object2ID { get; set; }
.....
public int Object1ID { get; set; }
    public Object2 myObject2 { get; set; }
}

感谢大家的帮助!我希望 lambda 表达式能够工作,它看起来更干净,尤其是当我开始添加更多包含时。

【讨论】:

    猜你喜欢
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    相关资源
    最近更新 更多