在多对多的关系中,你如何防止往返? - 实体框架

时间:2015-01-09 15:58:49

标签: entity-framework

这是我的数据模型的一个例子:

public class House : Record
{
    public string HouseNumber { get; set; }
    public string StreetName { get; set; }
    public int ZipCode { get; set; }

    public virtual ICollection<Street> Streets { get; set; } 
}

public class Street
{
    public int StreetId { get; set; }
    public string StreetName { get; set; }

    public virtual ICollection<House> HouseUnit { get; set; }
    public virtual ICollection<House> HouseUnitParallel { get; set; } 
}

我想从街道(不包括HouseUnit和HouseUnitParallel)获取每个房屋记录的StreetId和StreetName。

var entities = context.Houses.Include(r => r.Streets.Select(s => new 
{
     StreetId = s.StreetId, 
     StreetName = s.StreetName
}));

此代码抛出以下异常:

The Include path expression must refer to a navigation property defined on the type. 
Use dotted paths for reference navigation properties and the Select operator 
for collection navigation properties.

对于每一个House Record,我想在我的街道财产中排除HouseUnit和HouseUnitParallel集合(因为它背负着一堆房子到我的House记录中)。

我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:-1)

我想你想要这个:

var entities = context.Houses
                      .Include(r => r.Streets)
                      .SelectMany(h => h.Streets
                                        .Select(s => new 
                                        {
                                            StreetId = s.StreetId, 
                                            StreetName = s.StreetName
                                        }));

只要您没有在其他地方禁用延迟加载,您的虚拟ICollections将不会被急切加载,除非Include'd;应该省略HouseUnit和HouseUnitParallel。

修改

再看看导致异常的代码,可能是你只是过度思考:排除HouseUnit和HouseUnitParallel,你根本就不会Include

var entities = context.Houses.Include(r => r.Streets);

这将 - 再次假设您没有在其他地方禁用延迟加载 - 在Streets s返回的集合中包括House,但不包括Street上的关系;与

对比
var entities = context.Houses
                      .Include(r => r.Streets.Select(s => s.HouseUnits))
                      .Include(r => r.Streets.Select(s => s.HouseUnitParallel));

包含所有关系。

如果您尝试使用前者,并且仍然获得所有关系,则应该查看项目中其他位置是否已禁用延迟加载(即LazyLoadingEnabled = false)。即使它有,你也应该能够通过在LINQ查询之前调用context来为这个context.Configuration.LazyLoadingEnabled = true范围启用它。