我的实体模型设计错误或我做错了吗?

时间:2011-11-11 05:35:40

标签: database entity-framework-4.1 ef-code-first

在我的Winform应用程序中,我有SuppliersCustomersTransport Companies。它们是相似的,因为它们基本上是某种Contacts,但它们在可用字段方面略有不同。

例如,Suppliers需要StartDateEndDate个字段。目前即使SuppliersCustomers可能有多个联系人\实体,但我们不会在这些版本中执行此操作,但Transport companies将有多个联系人\实体和地址。同时,SupplierCustomer确实需要采购订单地址和递送地址,以及两个电话号码以防万一。

目前在我的代码优先实体中,我SuppliersCustomersTransport Companies各包含一个PrimaryContact类型,Contact类型Contact类型,我有ICollection AddressPhone,而Transport Companies又存储了一个或多个地址和电话信息。不同之处在于ContactPrimaryContact外还有Supplier的集合。

据我所知,即使我自己设计了DB / Entity,但BLL中的Objects并不总是完全映射下面的DB结构。 因此,我的想法是在我的BLL层中,我将数据从BOSupplier转换为Supplier到表示层,并在将数据从表示层返回到DAL时转换到Presentation。因为在我的Supplier图层中, public class BOSupplier { // Primery key public int ID { get; set; } public string Name { get; set; } public string TaxNumber { get; set; } public bool InActive { get; set; } public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } public string BankAccountNumber { get; set; } public string BankAccountName { get; set; } // Property related to Contact Table public string FirstName { get; set; } public string LastName { get; set; } public string EmailAddress { get; set; } public string SkypeName { get; set; } // Proterty related to Address Table // PO address Info public string POAddressLine { get; set; } public string POCity { get; set; } public string PORegion { get; set; } public string POCountry { get; set; } public string POPostCode { get; set; } // Delivery AddressLine public string DelAddressLine { get; set; } public string DelCity { get; set; } public string DelRegion { get; set; } public string DelCountry { get; set; } public string DelPostCode { get; set; } // Proterties related to Phone table public string PhoneNumber1 { get; set; } public string PhoneNumber2 { get; set; } } } 看起来像是:

Supplier

但在我的DAL图层中,我的public class Supplier { // Primery key public int ID { get; set; } public string Name { get; set; } public virtual Contact PrimaryContact { get; set; } public string TaxNumber { get; set; } public bool InActive { get; set; } public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } public string BankAccountNumber { get; set; } public string BankAccountName { get; set; } } 将如下所示:

BOSupplier

然后当我实际编写BLL类的代码来管理我的中间BOSupplier对象和List时,它实际上没有将实体映射回DB端。从两个略有不同的Supplierpublic static IEnumerable<BOSupplier> GetBOSuppliers() { var suppliers = dbContext.Suppliers; BOSupplier currentSupplier; foreach (Supplier supplier in suppliers) { currentSupplier = new BOSupplier() { ID = supplier.ID, Name = supplier.Name, Code = supplier.Code, FirstName = supplier.PrimaryContact.FirstName, TaxNumber = supplier.TaxNumber }; // PO Address Address poAddress = supplier.PrimaryContact.Addresses .FirstOrDefault<Address>(a => a.AddressTypeValue == (int)AddressTypes.Postal); if (poAddress != null) { currentSupplier.POAddressLine = poAddress.AddressLine1; currentSupplier.POCity = poAddress.City; currentSupplier.POCountry = poAddress.Country; } // Delivery Address Address delAddress = supplier.PrimaryContact.Addresses .FirstOrDefault<Address>(a => a.AddressTypeValue == (int)AddressTypes.Delivery); if (delAddress != null) { currentSupplier.DelAddressLine = delAddress.AddressLine1; currentSupplier.DelCity = delAddress.City; currentSupplier.DelCountry = delAddress.Country; } // ToDo: // There is probably more to think about how we want map multi phone numbers into limited two phone numbers if (supplier.PrimaryContact.Phones.Count > 0) { foreach (Phone phone in supplier.PrimaryContact.Phones) { if (phone.PhoneType == PhoneTypes.Default) { currentSupplier.PhoneNumber1 = phone.PhoneNumber; } else { currentSupplier.PhoneNumber2 = phone.PhoneNumber; } } } this.boSupplierList.Add(currentSupplier); } return boSupplierList; } 转移/映射字段似乎是一个很低级别的代码,如下所示:

BOSuppier

我一直在想:“也许我的实体模型应该更简单,或者有更好的方法来做我想做的事情?”。所以,请根据您的经验告诉我,我的实体模型过于复杂,或者我只需要更好的方法从Supplier映射到{{1}}或其他一些想法。

1 个答案:

答案 0 :(得分:0)

根据您对域的描述,您的实体模型并不复杂。您可以使用AutoMapperSupplier映射到BOSupplier。这是使用AutoMapper的example展平对象图。

我在GetBOSuppliers()中发现了问题。当您访问PrimaryContactAddresses时,它会使用延迟加载。为避免多次往返数据库,您可以按如下方式加载它们。

var suppliers = dbContext.Suppliers.Include(s => s.PrimaryContact.Addresses);