NHibernate正在改变我的收藏品。我怎么能阻止它?

时间:2009-10-15 23:41:01

标签: c# nhibernate collections fluent-nhibernate

我对Nhibernate / Fluent 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);
    }
}

我的Fluent 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:Collection is ReadOnly”而失败

似乎NHibernate在它的代理中正在做某事。有谁知道如何解决这个问题?

提前致谢。

3 个答案:

答案 0 :(得分:2)

如果在实体级别禁用延迟加载会发生什么?也就是说,确保NHibernate不为此类使用动态代理? (这对延迟加载集合的能力没有影响;延迟加载集合仍然有效。)

在我的应用程序中,我使用的方法与您在此处演示的方法相同(私有集合字段,包含集合的属性并返回只读列表),我没有那些问题,你是有。 但是,不同之处在于我在我的映射中声明(我不使用流畅的NHibernate,但是使用普通的旧xml文件:)),NHibernate不应该为我的类使用动态代理:

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

答案 1 :(得分:0)

鉴于子节点是私有字段,代理不可能对其进行修改,因为代理只能在虚拟字段和属性前面,除非有某种方法来设置不在代码中的子节点。它当然看起来非常奇怪,但我们需要看到适用于此的其他类。

答案 2 :(得分:0)

您的映射告诉nhibernate使用公共Children属性,因此它不会使用私有字段“children”。

我认为你不能在流畅的nhibernate映射中指定私有字段,所以如果你想要那样,你应该使用另一种映射策略,比如xml映射文件。

您可以执行以下操作以查看确实存在问题:

  • 将“儿童”字段公开(暂时只是为了测试)
  • 更改映射以使用“私有”小写子字段
  • 现在查看问题是否仍然存在