2011-11-11 49 views
0

在我的Winform應用程序中,我有Suppliers,Customers,Transport Companies。他們是相似的,因爲他們基本上是某種Contacts,但他們在可用字段方面略有不同。我實體模型的錯誤設計或者我做錯了?

例如Suppliers需要StartDateEndDate字段。而且,目前即使SuppliersCustomers可能有多個聯繫人\實體,但我們不打算在這些發佈中這樣做,但Transport companies將擁有多個聯繫人\實體和地址。同時,SupplierCustomer確實需要PO地址和傳送地址,以及兩個電話號碼以防萬一。

目前在我的代碼第一次實體,我有SuppliersCustomersTransport Companies每個包含PrimaryContact這是一個Contact類型,併爲每個Contact類型,我有Address一個ICollectionPhone這反過來存儲一個或以上一個地址和電話信息。不同之處在於Transport CompaniesPrimaryContact之外還將收集Contact。根據我的理解,即使我有自己設計DB/Entity的自由,BLL中的Objects並不總是正好映射下面的DB結構。 因此,這個想法是在我的BLL層,我會將數據從SupplierBOSupplier翻譯成表示層,並將數據從表示層返回到DAL時,將轉換爲Supplier。因爲在我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; } 
    } 
} 

但在我的DAL層,我Supplier會是這樣的:

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; } 
} 

後來,當我實際編寫代碼BLL類管理我的中間BOSupplier對象和List實際上沒有將實體映射回DB側。這似乎是一個很多低級別的代碼只是爲了轉移/地圖領域從兩個略有不同BOSupplierSupplier,像這樣:

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; 
} 

我一直在想:「也許我的實體模型應該是簡單的,或者有一些更好做我想做的事情的方式?「。因此,請根據您的經驗告訴我,我的實體模型過於複雜,或者我只需要一些更好的從BOSuppierSupplier或其他想法的映射方式。

回答

0

根據您對域的描述,您的實體模型並不複雜。您可以使用AutoMapper將您的Supplier映射到BOSupplier。這是使用AutoMapper展平對象圖的example

我在您的GetBOSuppliers()中看到問題。當您訪問PrimaryContactAddresses時,它使用延遲加載。要避免多次往返數據庫,您可以按如下方式加載它們。

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

感謝您的意見。是的,我同意這個結構並不複雜。但我不確定是否應該花時間編寫這個低級映射代碼,或者更好,使用映射器來爲我做這件事。但是,另一種選擇是不嘗試規範化聯繫人表格,而是使用平坦的模型/表格。我正在撰寫的應用程序是一個庫存跟蹤系統,它不僅僅是靈活的聯繫人列表。 –

+0

@pstar如果這種類型的查詢很常見,您可能會取消數據規範化。另一種選擇是使用微型ORM創建視圖和查詢。 – Eranga

+0

如果我想要同時加載兩個PrimaryContact SecondaryContact,該怎麼辦? –

相關問題