2009-10-15 27 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映射文件。

你可以做以下的,看看这确实是问题:

  • 让“孩子”领域的公众(现在,只是为了测试它)
  • 变化映射使用“私人”小写儿童场
  • 现在看到的,如果问题仍然存在
相关问题