C# 实体框架LINQ获取另一个集合的所有项

C# 实体框架LINQ获取另一个集合的所有项,c#,entity-framework,linq,C#,Entity Framework,Linq,从DBContext中获取与relationsCollection中的记录重叠的所有NWatchRelation记录。 相同的Id、RelatedNodeId和RelationType(enum:int)应该被视为匹配项 public class NWatchRelation : INWatchRelation { public int Id { get; set; } public int NodeId { get; set; } public NWatchNode N

从DBContext中获取与relationsCollection中的记录重叠的所有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();

您可以在这两个集合之间进行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;

在LINQ to Entities中完全实现这一点的唯一方法是手动编写
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);
}
IQueryable查询=null;
foreach(关系集合中的var关系)
{
var m=关系;
var subQuery=db.NWatchRelations
其中(r=>r.Id==m.Id
&&r.RelatedNodeId==m.RelatedNodeId
&&r.RelationType==m.RelationType);
query=query==null?子查询:query.Concat(子查询);
}

但请注意,这是一种有限的方法,如果
关系集合
很大,它将不起作用。

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

//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
是一个小集合,请使用您方便时先前提出的备选方案之一

您也可以像这样直接链接

[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();

我认为EF不支持对inmemory集合的联接。在
db.NWatchRelations
上添加一个
AsEnumerable()
,它应该可以工作,尽管性能可能是个问题。绝对正确@IvanStoev。谢谢你指出@朱哈尔。谢谢更新后包含了
asenumerale
(我想把
.ToList()
:)问题是什么?