2009-10-15 62 views
2

我有一點與NHibernate /功能NHibernate的一個問題NHibernate只是將我的集合只讀。我怎樣才能阻止它?

我有了一個收集和支持字段,併爲操作收集像這樣方法的類:

編輯:已經添加了虛擬修飾符Children因爲我忘了堅持在下面的示例代碼(這是凌晨2點)

public class MyClass 
{ 
    private IList<SomeChildObject> children; 

    public virtual IList<SomeChildObject> Children { get { return new ReadOnlyCollection<SomeChildObject>(children); } } 

    public void AddToChildren(SomeChildObject obj) 
    { 
     children.Add(obj); 
    } 
} 

我有我的功能NHibernate映射是這樣的:

public class MyClassMapping : ClassMap<MyClass> 
{ 
    public MyClassMapping() 
    { 
     HasMany(x => x.Children) 
      .Inverse() 
      .LazyLoad() 
      .Cascade.AllDeleteOrphan() 
      .KeyColumnNames.Add("MyClassID") 
      .Access.AsReadOnlyPropertyThroughCamelCaseField(); 
    } 
} 

現在,當我從數據庫中撤回MyClass的實例時,所有這一切都很好。

MyClass myClass = repo.GetById(12); 

myClass.AddToChildren(new SomeChildObject()); 

這工作正常。

然後我做了一些更改並將更改持久化到數據庫。

一旦更改已保存,然後我嘗試添加另一個子對象

myClass.AddToChildren(new SomeChildObject("Another One!!!")); 

而且它倒下「出現InvalidOperationException:集合是隻讀的」

似乎NHibernate的做事情代理中的某個地方。有誰知道如何解決這個問題?

在此先感謝。

+0

哪裏私營孩子得到初始化?我期望'children.Add(obj);'的空引用。 – dotjoe 2009-10-19 20:19:13

回答

2

如果您在實體級別上禁用延遲加載會發生什麼?也就是說,確保NHibernate不爲這個類使用動態代理? (這對延遲加載集合的能力沒有影響;延遲加載集合仍然有效)。在我的應用程序中,我使用了與您在此演示的方法相同的方法(私有集合字段,包含集合的屬性並返回只讀列表),並且我沒有那些問題,重新擁有。 但是,不同的是,我在映射聲明(我不使用流利NHibernate的,但普通的老式XML文件:)),即NHibernate的不應該使用動態代理我的課:

<class name="SomeClass" table="SomeTable" lazy="false"> 
     <!-- rest of mapping goes here --> 
    </class> 
+0

我會看看Fluent NHibernate是否有相同的功能(如果沒有的話,會感到驚訝)感謝您的建議 – Sekhat 2009-10-19 10:04:22

+0

確實有可能 'SetAttribute(「lazy」,「false」)'做了訣竅:) – Sekhat 2009-10-24 13:28:26

0

考慮到孩子是一個私人領域,代理不可能修改它,因爲代理只能在虛擬領域和屬性前面,除非有一些方法可以設置不在代碼中的子代。它看起來非常怪異,但我們需要看到適用於此的其他課程。

+0

除了在構造函數中,沒有別的方法可以設置'children'。 – Sekhat 2009-10-16 08:49:35

+0

(它用'new List ()'初始化它'' – Sekhat 2009-10-16 08:50:10

0

你映射告訴nhibernate使用公共兒童財產,所以它不會使用私人領域的「兒童」。

我不認爲你可以在流利的nhibernate映射中指定私有字段,所以如果你想要的話,你應該使用替代映射策略,如xml映射文件。

你可以做以下的,看看這確實是問題:

  • 讓「孩子」領域的公衆(現在,只是爲了測試它)
  • 變化映射使用「私人」小寫兒童場
  • 現在看到的,如果問題仍然存在