Неправильный дизайн моих моделей сущностей или я делаю это неправильно? - PullRequest
0 голосов
/ 11 ноября 2011

в моем приложении Winform, у меня есть Suppliers, Customers, Transport Companies.Они похожи, так как они в основном своего рода Contacts, однако они немного различаются с точки зрения доступных полей.

Например, Suppliers необходимо иметь поля StartDate и EndDate.И в настоящее время, хотя Suppliers и Customers могут иметь более одного контактного лица \ сущности, но мы не собираемся делать это в этих выпусках, но Transport companies будет иметь более одного контактного лица \ сущности и адреса.В то же время, Supplier и Customer требуют адрес PO и адрес доставки, а также два телефонных номера на всякий случай.

В настоящее время в моем Code First Entities у меня есть Suppliers, Customers и Transport Companies, каждый из которых содержит PrimaryContact типа Contact, и для каждого типа Contact у меня естьICollection из Address и Phone, которые, в свою очередь, хранят один или несколько адресов и информацию о телефоне.Разница в том, что Transport Companies будет иметь коллекцию Contact в дополнение к PrimaryContact.

. Как я понимаю, даже у меня есть свобода проектирования БД / сущности в одиночку, не всегдаслучай, когда Objects в BLL является точно отображением структуры БД внизу.Таким образом, идея находится в моем слое BLL, я переведу данные из Supplier в 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; }
    }
}

Но в моем слое 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, который фактически не отображает обратно сущность на сторону БД.Кажется, много низкоуровневого кода просто для передачи / сопоставления полей из двух слегка отличающихся BOSupplier и 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;
}

Я продолжаю думать: «Возможно, моя Entity Model должна быть прощеили есть какой-то лучший способ сделать то, что я пытаюсь сделать? "Поэтому, исходя из вашего опыта, скажите мне, что моя модель сущностей слишком сложна, или мне просто нужен какой-то лучший способ сопоставления с BOSuppier до Supplier или какие-то другие мысли.

1 Ответ

0 голосов
/ 11 ноября 2011

Ваша модель сущности не является сложной в соответствии с вашим описанием домена. Вы можете использовать AutoMapper для сопоставления вашего Supplier с BOSupplier. Вот пример сглаживания графа объекта с использованием AutoMapper.

Я вижу проблему в вашем GetBOSuppliers(). Он использует отложенную загрузку при доступе к PrimaryContact и Addresses. Чтобы избежать многократных обращений к базе данных, вы можете загрузить их следующим образом.

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