簡體   English   中英

使用EF4 CTP5中的POCO以多對一關系刪除子實體

[英]Deleting a child entity in a many-to-one relationship using POCO in EF4 CTP5

簡潔版本:

使用經典的Order和OrderLine示例,如何在POCO中執行以下操作:

public partial class Order {

    public void RemoveInvalidOrderLines() {
        OrderLines.Remove(OrderLines.Where(ol => ol.Quantity > MaxQuantity));
    }
}

在使用POCO的多對一關系中,這僅刪除OrderLine中對Order的引用。 有沒有辦法自動刪除OrderLine實體? 或者我是否必須注入存儲庫或將代碼提升到服務中? 在數據庫中使用觸發器? 這有什么模式或最佳實踐嗎? 我在網上找到的所有例子似乎都使用了一些簡單的添加和“這就是你應該使用POCO的原因”:-)

情況:

在VS2010中使用EF4 CTP5,生成持久性無知的POCO(動態代理),我在如何處理刪除相關的“子”實體方面遇到了困難。

問題:下面的Employee類中的ICollection Relative中的Remove方法僅刪除關系,而不刪除最終實體。 有沒有辦法強制它刪除實體,而無需注入存儲庫/服務或從實體中提取代碼? 我想要一個干凈的POCO類。

動機:沒有員工,相對實體不可能存在,因此處理添加,刪除等最自然的地方是在Employee類中。 再說一遍,我願意接受建議。 :-)

示例:一個員工可以擁有多個親戚。 Employee類有一個存儲庫,提供常用的查找程序。 我希望Employee能夠刪除親屬,而不僅僅是FK關系。 我是否必須注入存儲庫或類似物才能執行此操作? 我試圖將上下文和存儲庫保留在POCO之外。

假設以下表格:

Employee:             
Id int (PK, not null)
Name varchar

Relative:
 Id int (PK, not null)
 EmployeeId int (FK, not null)
 Name varchar

生成以下POCO:

public partial class Employee {
...
    public virtual ICollection<Relative> Relatives
    {

        get
        {
            if (_relatives == null)
            {
                var newCollection = new FixupCollection<Relative>();
                newCollection.CollectionChanged += FixupRelatives;
                _relatives = newCollection;
            }
            return _relatives;
        }
        set
        {
            if (!ReferenceEquals(_relatives, value))
            {
                var previousValue = _relatives as FixupCollection<Relative>;
                if (previousValue != null)
                {
                    previousValue.CollectionChanged -= FixupRelatives;
                }
                _relatives = value;
                var newValue = value as FixupCollection<Relative>;
                if (newValue != null)
                {
                    newValue.CollectionChanged += FixupRelatives;
                }
            }
        }
    }

而且當然,

Relative:
public partial class Relative {
...
 public virtual Employee Employee
    {
        get { return _employee; }
        set
        {
            if (!ReferenceEquals(_employee, value))
            {
                var previousValue = _employee;
                _employee = value;
                FixupEmployee(previousValue);
            }
        }
    }
    private Employee _employee;


}

現在,人們可以這樣做:

var employeeRepository = new EmployeeRepository(dbContext);
var employee = employeeRepository.Get(1234);
var relative = new Relative { Name = "Lars" };
employee.Relatives.Add(relative); 
context.SaveChanges();

並將相對內容添加到Relative表中,並引用該員工。

但是,如果我想在Employee-class中實現DeleteRelative方法:

public void DeleteRelative(string name) {
     Relatives.Remove(Relatives.FirstOrDefault());
}

(天真的代碼假設親戚存在等)

我明白了:

System.InvalidOperationException: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

這是完全可以理解的,因為Relative中的EmployeeId字段不能為null。

因此,除了將存儲庫/上下文注入到實體中之外,還有可能以任何方式解決這個問題(恕我直言,這種方式違背了POCO的目的)。

另一種方法是將它全部包裝在服務或事務腳本中,但同樣,我希望EF4能夠在沒有配置/連接實體或執行事務腳本的情況下處理這個問題。

非常感謝任何幫助,如果您需要更多信息,請告訴我。

哦,祝大家新年快樂。 :-)

如果它是應用程序架構中的一個選項,您可以考慮在您的實體上啟用動態代理。 這使上下文能夠創建實體的子類,從而覆蓋您的屬性以跟蹤更改。 在您的情況下,當對象丟失它的引用時,這將刪除與您的對象相對應的行(假設您在上下文中調用SaveChanges())。

可以在啟用動態代理時啟用

  • 該課程是公開的,沒有密封。
  • 該類具有公共或受保護的屬性(在您的示例中特別是包含“訂單行”的集合屬性)。
  • 該類具有公共或受保護的無參數構造函數。

看看這個問題,你似乎滿足了這些要求。

啟用動態代理可以通過在上下文中設置屬性來完成(也可以在Entity Framework設計器視圖中完成):

this.ContextOptions.ProxyCreationEnabled = true;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM