2015-09-22 2 views
1

у меня есть проект, который имеет множество таблиц, которые потребуют адрес:Entity Framework 6, таблица со ссылками на нескольких других таблиц

  • Заказчик
  • Заказать
  • Производитель
  • ... много Больше.

Вместо CustomerAddress, OrderAddress и VendorAddress стол, мы пытаемся использовать общий адрес таблицы вроде этого:

AddressId (PK, int, identity, not null) 
AddressType (int, not null, poss values: Customer, Order, Vendor, etc..) 
ForeignKeyId (int, not null) 
Name 
Street 
City 
etc... 

И таблица клиентов:

CustomerId (PK, int, identity, not null) 
...other customer information... 

Где если у меня был Клиент (CustomerId = 56), может быть адресная запись, например:

AddressId (some number) 
AddressType = 1 (Customer) 
ForeignKeyId = 56 
Name, Street, City 

Это все хорошо и хорошо.

Однако проблема возникает, когда я иду добавить нового Клиента в систему. В EF, я думаю, это означает, что я должен добавить клиента, SaveChanges(), а затем добавить адрес отдельно.

Customer c = new Customer { ... }; 
context.Customer.Add(c); 
context.SaveChanges(); // In order to get the CustomerId to be filled in 
Address a = new Address { AddressType = 1, ForeignKeyId = c.CustomerId }; 
context.Address.Add(a); 
context.SaveChanges(); 

Это вызывает несколько проблем структурно с кодом. Во-первых, как все идет, мы не можем добавлять Клиента и адрес в одно и то же место. Во-вторых, что более важно, это требует двух SaveChanges(), что означает, что мы больше не получаем транзакцию (или нам нужно сделать свою собственную транзакцию и нести ее).

То, что я хотел бы сделать, это больше похоже на это:

Customer c = new Customer { ... }; 
context.Customer.Add(c); 
Address a = new Address { AddressType = 1 }; 
context.Address.Add(a); 
// Somehow magic happens and Address can be associated with 
// Customer as soon as we have a CustomerId assigned. 
context.SaveChanges(); 

Я знаю, что нет никакой магии, но есть способ для меня, чтобы сделать то, что я хочу с одним SaveChanges()?

Редактировать: Если это актуально, это база данных First EF.

ответ

1

Если база данных не имеет отношения между таблицами, вам необходимо добавить() каждый объект, а затем SaveChanges().

Какова связь между двумя, например, один-к-одному, один-ко-многим?

Имея отношения позволяет писать код так:

Customer c = new Customer 
{ 
    ... 
    Address = new Address { AddressType = 1 } 
}; 

context.Customer.Add(c); 
context.SaveChanges(); 

Если вы не имеете отношения базы данных, созданные и вы не можете сделать это, вы должны быть в состоянии виртуализировать отношения в вашем EM ,

В файле класса Context, изменить

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    //default statement 
    //throw new UnintentionalCodeFirstException(); 

    //establish the one-to-zero-or-one relation 
    modelBuilder.Entity<Customer>() 
     .HasOptional(c => c.Address); 
} 

Добавить подходящую недвижимость для ваших клиентов и адресов классов. В качестве примера для отношения «один к одному».

public virtual Address Address {get; set;} в Клиента и public virtual Customer Customer {get; set;} в адрес

Я обновить OnModelCreating() в ближайшее время. У меня встреча. Если у кого-то есть какие-то дополнительные, просто бросьте его в комментарии (надеюсь, я не слишком взвинчен).

EDIT См. Это SO answer для установления отношений.

EDIT 2 IRT DB Во-первых, до тех пор, как таблицы в том же контексте, если вам нужно только SaveChanges() один раз. Чтобы обеспечить одинаковый контекст в DAO, инициализируйте контекст, когда создается DAO.

private DbEntities db = new DbEntities();

Вы бы затем использовать этот экземпляр db контекста во всем.

+0

База данных не имеет отношения к ней, она не может, поскольку адрес может указывать на Заказ, Заказ, Поставщик и те таблицы, на которые не ссылается. Это было бы взаимно-однозначное отношение. Я ценю ответ до сих пор, я рассматриваю, как это будет работать. –

+0

Итак, глядя на ответ SO, на который вы ссылаетесь, это строго между двумя таблицами? В этом случае адрес имеет дополнительный клиент, также имеет необязательный заказ, также имеет опционный поставщик. –

+0

С помощью Edit2 я думаю, что вам не хватает точки, в которой для Customer необходимо указать CustomerId (ForeignKeyId), что означает, что это двухэтапная операция. CustomerId не заполняется/присваивается до тех пор, пока не произойдет SaveChanges(). –

Смежные вопросы