实体框架 - 渴望加载,列出所有属性

时间:2014-06-19 09:57:19

标签: entity-framework eager-loading

我有一个简单的项目,其中我有以下模型。

Customer 1--->N Addresses N<----1 City N<----1 Country
                     ^
                    N|
                     |
AddressTypes 1-------+

这是我的代码:

public partial class Customer {
        public Customer() {
            this.Address = new HashSet<Address>();
        }
        public int Id {get;set;}
        public string FirstName {get;set;}
        public string LastName {get;set;}
        public System.DateTime Birthday {get;set;}

        public virtual ICollection<Address> Address {get;set;}
    }

public partial class Address {
        public int Id {get;set;}
        public string Street {get;set;}
        public string Area {get;set;}
        public string Post {get;set;}
        public bool isDeleted {get;set;}

        public virtual Customer Customer {get;set;}
        public virtual City City {get;set;}
        public virtual AddressType AddressType {get;set;}
    }

public partial class AddressType {
        public AddressType() {
            this.Address = new HashSet<Address>();
        }
        public int Id {get;set;}
        public string Name {get;set;}

        public virtual ICollection<Address> Address {get;set;}
    }

public partial class Country {
        public Country() {
            this.City = new HashSet<City>();
        }
        public int Id {get;set;}
        public string Name {get;set;}

        public virtual ICollection<City> City {get;set;}
    }

public partial class City {
        public City() {
            this.Address = new HashSet<Address>();
        }
        public int Id {get;set;}
        public string Name {get;set;}

        public virtual ICollection<Address> Address {get;set;}
        public virtual Country Country {get;set;}
    }


public partial class MyModelContext : DbContext {
        public MyModelContext()
            : base("name=MyModelContext") {
            this.Configuration.LazyLoadingEnabled = true;
            this.Configuration.ProxyCreationEnabled = false;
        }

        public virtual DbSet<Country> Countries {get;set;}
        public virtual DbSet<City> Cities {get;set;}
        public virtual DbSet<AddressType> AddressTypes {get;set;}
        public virtual DbSet<Address> Addresses {get;set;}
        public virtual DbSet<Customer> Customers {get;set;}
    }

我想返回一份客户列表。起初我试着做一个简单的Customers.ToList(),但我得到一个exception during serialization,我读到这是由周期性引用引起的。所以我添加了

Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = false;

然后我能够得到客户,但没有地址。我试过了:

public List<Customer> getCustomers() {
    MyModelContext db = new MyModelContext();
    return db.Customers.Include("Address").ToList();
}

但我不知道如何检索所有属性。我想列出每个客户和他的地址列表,包括城市,国家,每个地址的地址类型。我该怎么办?

2 个答案:

答案 0 :(得分:1)

您有几种选择:

1。使用DTO(Data Transfer Objects)。

2。通过应用以下属性,显式忽略包含对父对象的循环引用的有问题的属性:

// in Address entity
[IgnoreDataMember]
[XmlIgnore]
[NonSerialized]
public Customer Custom { get; set; }

同样位于AddressType.AddressCity.AddressCountry.City

3. 将您的实体投射到匿名对象中并排除pr:

db.Customers.Select(c => new
            {
                c.Id,
                c.FirstName,
                c.LastName,
                c.Birthday,
                Address = c.Address.Select<Address, object>(a => new
                {
                    a.Id,
                    AddressType = new
                    {
                        a.AddressType.Id,
                        a.AddressType.Name
                    },
                    a.Area,
                    City = new
                    {
                        a.City.Id,
                        Country = new
                        {
                            a.City.Country.Id,
                            a.City.Country.Name
                        },
                        a.City.Name,
                    },
                    a.Post,
                    a.Street,
                    a.isDeleted
                }),
            });

您必须重新启用LazyLoadingEnabledProxyCreationEnabled才能使其正常工作(或使用Include)。

(作为旁注,我真的不明白为什么你需要这个循环引用,你从AddressType.Address得到什么好处?)

答案 1 :(得分:0)

我这样解决了:

public List<Customer> getCustomers() {

            var customers = db.CustomerSet.Include("Address")
                .Include("Address.AddressType")
                .Include("Address.City")
                .Include("Address.City.Country")
                .ToList();

            return customers;
        }

我真的不喜欢我必须明确地写下客户的所有属性,并且没有一种通用的方式来做我想要的但它有效。