EF预测多对多不加载

时间:2015-08-19 17:28:17

标签: entity-framework entity-framework-6

我有四个类定义如下:

public class Operator : Base
{
    public string Name { get; set; }
    public string URL { get; set; }
    public ICollection<Address> Addresses { get; set; }
    public ICollection<Contact> Contacts { get; set; }
    public ICollection<Application.Application> Applications { get; set; }
}


public class Address : Base
{
    public String Street{ get; set; }

    public int? ParentId { get; set; }
    public Operator Parent { get; set; }

    public ICollection<Application.Application> Applications { get; set; }
}



public class Contact : Base
{
    public string Name { get; set; }

    public int? ParentId { get; set; }
    public Operator Parent { get; set; }

    public ICollection<Application.Application> Applications { get; set; }
}


public class Application : Base
{
    [MaxLength(300)]
    public String Name { get; set; }

    public ICollection<Operator.Operator> Operators { get; set; }
    public ICollection<Operator.Address> Addresses { get; set; }
    public ICollection<Operator.Contact> Contacts { get; set; }
}

public class Base
{
    public int Id { get; set; }
    //public int BaseObjectId { get; set; }
    TimeZoneInfo _easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

    private DateTime _modifiedDate;
    public DateTime ModifiedDate
    {
        get { return this._modifiedDate; }
        set
        {
            this._modifiedDate = DateTime.SpecifyKind(value, DateTimeKind.Unspecified);
            this._modifiedDate = TimeZoneInfo.ConvertTimeFromUtc(this._modifiedDate, _easternZone);
        }
    }

    private DateTime _createdDate;
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime CreatedDate
    {
        get { return this._createdDate; }
        set
        {
            this._createdDate = DateTime.SpecifyKind(value, DateTimeKind.Unspecified);
            this._createdDate = TimeZoneInfo.ConvertTimeFromUtc(this._createdDate, _easternZone);
        }
    }

    public bool Disabled { get; set; }
}


public class DB : DbContext
{
    public DbSet<EF.Complaint.Complaint> Complaints { get; set; }
    public DbSet<EF.Category.Category> Categories { get; set; }
    public DbSet<EF.Action.Action> Actions { get; set; }
    public DbSet<EF.Medium.Medium> Mediums { get; set; }
    public DbSet<EF.Priority.Priority> Priorities { get; set; }
    public DbSet<EF.Complaint.Comment> Comments { get; set; }

    public DB()
    {
        this.Database.Log = s => { System.Diagnostics.Debug.WriteLine(s); };
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
        modelBuilder.Configurations.Add(new ComplaintConfig());
        modelBuilder.Configurations.Add(new CategoryConfig());
        modelBuilder.Configurations.Add(new ActionConfig());
        modelBuilder.Configurations.Add(new MediumConfig());
        modelBuilder.Configurations.Add(new PriorityConfig());
        modelBuilder.Configurations.Add(new CommentConfig());

        base.OnModelCreating(modelBuilder);
    }
}

OperatorContactAddress都可以属于特定的应用程序。所以你可以有这样的结构:

运营商1 - 属于App1和App2

儿童联系人1 - 属于App1

儿童联系2 - 属于App2

子地址1 - 属于App2

我正在尝试构建一个方法,该方法返回特定应用程序的运算符列表,并包括该运算符的地址和联系人,该运算符也属于该应用程序

这是我到目前为止编造的查询

public IEnumerable<Operator> GetForApp(string name)
    {            
        return (Context.Operators.Where(x => x.Applications.Any(y => y.Name == name))
            .Select(x => new
            {
                x,
                Addresses = x.Addresses.Where(y => y.Applications.Any(z => z.Name == name)),
                Contacts = x.Contacts.Where(y => y.Applications.Any(z => z.Name == name)),
                Applications = x.Applications
            }).AsEnumerable()
        .Select(n => n.x));
    }

这在某种意义上起作用,Operator的基本成员加载以及AddressesContacts正确加载和过滤......未加载的内容是{ {1}}我无法弄清楚原因。我们看到的唯一区别是Applications / AddressesContacts是多对一的,OperatorApplications是多对多的。< / p>

1 个答案:

答案 0 :(得分:0)

您必须使用延迟加载功能或直接在查询中包含相关对象。

public class Operator : Base
{
    public string Name { get; set; }
    public string URL { get; set; }
    public ICollection<Address> Addresses { get; set; }
    public ICollection<Contact> Contacts { get; set; }
    // by adding virtual keyword EF could generate proxy classes and 
    // fetch actual objects when are needed. 
    public virtual ICollection<Application.Application> Applications { get; set; }
}

或者在您的查询中直接包含Application

public IEnumerable<Operator> GetForApp(string name)
{            
    return (Context.Operators.Where(x => x.Applications.Any(y => y.Name == name))
        .Include(x=>x.Applications)
        .Select(x => new
        {
            x,
            Addresses = x.Addresses.Where(y => y.Applications.Any(z => z.Name == name)),
            Contacts = x.Contacts.Where(y => y.Applications.Any(z => z.Name == name)),
            Applications = x.Applications
        }).AsEnumerable()
    .Select(n => n.x));
}