none
实体外键更新的问题? RRS feed

  • 問題

  • 请教一下,比如说:CustomerEntity中有一个AddressEntity,那么我在更新的时候如果一起更新AddressEntity这个相关联的实体?
    因为以前在LINQ中并不是使用实体的,而是会有一个AddressId的,但现在为什么是一个实体了?我应该如何更新这个AddressId呢?谢谢!

    代码我是这样写的:
    addressEntity = new AddressEntity();
    addressEntity.AddressName = "Street 1";

    customer.AddressEntity = addressEntity;

    然后context.AddToCustomer(customer);

    同时,我试过用Attach(customer);提示“System.InvalidOperationException: 无法将具有 null EntityKey 值的对象附加到对象上下文。
       在 System.Data.Objects.ObjectContext.Attach(IEntityWithKey entity)”。
    请问我该如何做?谢谢!

    2009年3月5日 上午 05:20

所有回覆

  • 你的需求是指更新嗎?如果是

    不要自行new AddressEntity物件然後指定給CustomerEntity.
    改用以下方式

    AddressEntity addressEntity = customer.AddressEntity;
    addressEntity.AddressName = "Street 1";

    context.SaveChange();

    這樣就可以了.

    2009年3月5日 上午 10:03
  • programlin,谢谢你的回复。
    如果我代码这样写呢:
    我想把addressEntity指定是属于哪个customer的,
    CustomerEntity customerEntity = addressEntity.CustomerEntity;
    但是addressEntity中的Customer是NULL的。像我说的这种情况应该怎么写?
    因为CustomerEntity肯定是从已经存在的记录中SELECT的,就是不明白如何给addressEntity.Customer?
    麻烦再解答一下。谢谢!

    2009年3月6日 上午 02:13
  • 如果我把CustomerEntity先SELECT出来,然后addressEntity.CustomerEntity = SELECT出的那个CustomerEntity,然后报出以下错误:
    “无法将具有 null EntityKey 值的对象附加到对象上下文。”
    2009年3月6日 上午 02:38
  •  你的問題有兩種情況
    1.CustomerEntity是一個已經存在於資料庫中的資料,你只是想更新addressEntity.Customer的對應關係
    如果address也已經存在於資料庫
    CustomerEntity customer = context.Customers.First(c => c.id==1);  
    AddressEntity address = context.Addresses.First(a => a.id==1);  
     
    address.Customer = customer;  
    context.SaveChanges();  
     
     
    如果address不存在於資料庫
    AddressEntity address = new AddressEntity();
    ...
    context.AddToAresses(address);
    context.SaveChanges();


    CustomerEntity customer = context.Customers.First(c => c.id==1);         
    address.Customer = customer;     
    conext.SaveChanges();     
        
        
     


    如上因為EF的機制是它將關聯的物件新增部分的機制交由使用者來決定(有些ORM不是這樣做,像NHibernate,但實際上自動化不見得好,我在NHibernate最後幾乎也都改為手動,因自動機制有時候會產生些矛盾問題,所以我認同EF這種作法,比較明確許多)
    簡單的說Entity一定要先attach到context上.用context將資料取出是一種做法,另一種做法是用Attach方法,但這通常用於像WebService往訪時狀態消失時處理.一般new 出來的物件不會這樣做.

    2.CustomerEntity本身是一個新的資料需要新增到資料庫中
    這部分你可以自行推出做法.
    2009年3月6日 上午 03:25
  • 谢谢回答,你说的是都是在DAL中完成的,但是我生成实体类和实体与外键的关系都是放在UI层做的,所以可能会导致我的问题。
    2009年3月6日 上午 03:52
  • 其實並沒有影響,你會如此認為應該是架構上的問題,我用底下,Customer對員工的新增功能Code

    Bussines Logic

    Public class AddCustomerTransaction  
    {  
    private string _customerName;  
    ...  
    private List<Contact> _contacts = new List<Contact>();  
     
     
     
    public AddCustomerTransaction(string customerName, ....)  
    {  
    this.customerName = customerName;  
    ...  
    }  
     
    public void AddContact(string name,...)  
    {  
    Employee emp = new Employee();  
    emp.Name = name;  
    ...  
     
    this._contacts.Add(emp);  
    }  
     
    public Customer Execute()  
    {  
    ObjectContext context = new ObjectContext();  
    //如需要這邊可以啟用交易
    Customer cus = new Customer();  
    cus.Name = this._customerName;  
    ...  
    context.SaveChanges();  
     
    foreach(Contact contact in this._contacts)  
    {  
    contact.Customer = cus;  
    context.AddToContact(contact);  
    }  
    context.SaveChanges();  
     
    return cus;  
    }  
     
    UI
    AddCustomerTransaction tran = new AddCustomerTransaction("...", ...);     
    tran.AddContact("...", ...);     
    tran.AddContact("...", ...);     
    tran.AddContact("...", ...);     
    ...     
        
    Customer cus = tran.Execute();     
        
    foreach(Contact contact in cus.Contacts)     
    {     
    ....     
    }    
     

    至於DAL,廣義的來說Entity Framework本身就是,至少你用EDM工具產出的Code很明顯就是了.

    所以你現在的問題在於你做了分層也用了ORM但程式實際上並沒有用OO觀念在撰寫,其實ORM跟分層最終還是靠OO這個基礎.
    簡單來說一個新增或修改的動作不單單只是針對資料庫作處理而應該是一連串的動作,這些問題在OO中都有解答.
    2009年3月6日 上午 07:00