实体框架6,包含对多个其他表

时间:2015-09-22 13:37:57

标签: c# entity-framework tsql

我有一个项目有很多表需要一个地址:

  • 客户
  • 顺序
  • 供应商
  • ......还有更多。

我们不是尝试使用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()完成我想要的东西吗?

修改:如果相关,则为数据库优先EF。

1 个答案:

答案 0 :(得分: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()。我参加了一个会议。如果有人有任何额外的,只需把它扔进评论中(希望我不会太过分了)。

修改 请参阅此SO answer以设置关系。

编辑2 IRT DB首先,只要表位于相同的上下文中,您只需要SaveChanges()一次。要确保DAO中的上下文相同,请在实例化DAO时初始化上下文。

private DbEntities db = new DbEntities();

然后,您将在整个过程中使用此db上下文实例。