在我的Winform应用程序中,我有Suppliers
,Customers
,Transport Companies
。它们是相似的,因为它们基本上是某种Contacts
,但它们在可用字段方面略有不同。
例如,Suppliers
需要StartDate
和EndDate
个字段。目前即使Suppliers
和Customers
可能有多个联系人\实体,但我们不会在这些版本中执行此操作,但Transport companies
将有多个联系人\实体和地址。同时,Supplier
和Customer
确实需要采购订单地址和递送地址,以及两个电话号码以防万一。
目前在我的代码优先实体中,我Suppliers
,Customers
和Transport Companies
各包含一个PrimaryContact
类型,Contact
类型Contact
类型,我有ICollection
Address
和Phone
,而Transport Companies
又存储了一个或多个地址和电话信息。不同之处在于Contact
除PrimaryContact
外还有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端。从两个略有不同的Supplier
和public 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}}或其他一些想法。
答案 0 :(得分:0)
根据您对域的描述,您的实体模型并不复杂。您可以使用AutoMapper将Supplier
映射到BOSupplier
。这是使用AutoMapper的example展平对象图。
我在GetBOSuppliers()
中发现了问题。当您访问PrimaryContact
和Addresses
时,它会使用延迟加载。为避免多次往返数据库,您可以按如下方式加载它们。
var suppliers = dbContext.Suppliers.Include(s => s.PrimaryContact.Addresses);