【问题标题】:Entity Framework LINQ Get all items part of another collection实体框架 LINQ 获取另一个集合的所有项目的一部分
【发布时间】:2016-04-08 18:12:41
【问题描述】:

从 DBContext 中获取与关系集合中的记录重叠的所有 NWatchRelation 记录。 相同的 Id、RelatedNodeId 和 RelationType (enum: int) 应该被视为匹配项。

public class NWatchRelation : INWatchRelation
{
    public int Id { get; set; }
    public int NodeId { get; set; }
    public NWatchNode Node { get; set; }
    public int RelatedNodeId { get; set; }

    public NWatchNode RelatedNode { get; set; }
    public NWatch.NWatchRelationType RelationType { get; set; }
}

INWatchRelation[] relationsCollection = GetRelations();

【问题讨论】:

  • 有什么问题?

标签: c# entity-framework linq


【解决方案1】:

您可以在这两个集合之间进行 LINQ 连接。

var result = from a in db.NWatchRelations.AsEnumerable()
             join b in relationsCollection on a.RelatedNodeId equals b.RelatedNodeId
                                           && a.Id equals b.Id
                                           && a.RelationType equals b.RelationType 
             select a;

【讨论】:

  • 我认为 EF 不支持加入内存集合。
  • db.NWatchRelations 上打一个AsEnumerable(),它应该可以工作,尽管性能可能是个问题。
  • 绝对正确@IvanStoev。感谢您指出。 @juhaar。谢谢。更新为包括AsEnumberale(我打算放.ToList() :))
【解决方案2】:

在 LINQ to Entities 中完全做到这一点的唯一方法是使用 Queryable.Concat 手动编写 UNION ALL 查询,如下所示:

IQueryable<NWatchRelation> query = null;
foreach (var relation in relationsCollection)
{
    var m = relation;
    var subQuery = db.NWatchRelations
        .Where(r => r.Id == m.Id
            && r.RelatedNodeId == m.RelatedNodeId
            && r.RelationType == m.RelationType);
    query = query == null ? subQuery : query.Concat(subQuery);
}

但请注意,这是一种有限的方法,如果relationsCollection 很大,则无法使用。

【讨论】:

    【解决方案3】:

    您可以使用这三个值创建一种唯一键:

    //To create a unique key (an string, which is a primitive type) combining the three values
    var keys=relationsCollection.Select(e=>e.Id+"-"+e.RelatedNodeId+"-"+ ((int)e.RelationType)).Distinct();
    
    var query=db.NWatchRelations.Where(r=>keys.Any(k=>k == (SqlFunctions.StringConvert((double)r.Id)+"-"+
                                                            SqlFunctions.StringConvert((double)r.RelatedNodeId )+"-"+ 
                                                            SqlFunctions.StringConvert((double)((int)r.RelationType)) ));
    

    如果您的NWatchRelations 表没有很多行或relationsCollection 是一个小集合,请在方便的情况下使用之前提出的替代方案之一。

    【讨论】:

      【解决方案4】:

      你也可以像这样直接链接

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
          public NWatchRelation()
          {
              this.INWatchRelation = new HashSet<INWatchRelation>();
          }
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
          public virtual ICollection<INWatchRelation> INWatchRelation { get; set; }
      

      但是整个关系必须像这样才能正常工作

      然后你可以像这样选择/列出它

      db.NWatchRelation.INWatchRelation.ToList();
      

      【讨论】:

        猜你喜欢
        • 2019-07-25
        • 2011-05-09
        • 1970-01-01
        • 1970-01-01
        • 2013-12-21
        • 1970-01-01
        • 1970-01-01
        • 2016-05-13
        • 1970-01-01
        相关资源
        最近更新 更多