我对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在它的代理中正在做某事。有谁知道如何解决这个问题?
提前致谢。
答案 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映射文件。
您可以执行以下操作以查看确实存在问题: