开发者

NHibernate is turning my collection readonly. How can I stop it?

I'm having a bit of an issue with Nhibernate / Fluent NHibern开发者_如何学运维ate

I have a class that has a collection and a backing field, and methods for manipulating the collection like so:

Edit: I've added the virtual modifier to Children since I forgot to stick it in the example code below (it was 2 am)

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);
    }
}

And I have my Fluent NHibernate mapping like this:

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

Now all is good when I pull back an instance of MyClass from the database.

MyClass myClass = repo.GetById(12);

myClass.AddToChildren(new SomeChildObject());

This works fine.

And then I make some changes and persist the changes to the database.

Once the changes have been saved, I then try and add another child object

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

And it falls over with "InvalidOperationException: The Collection is ReadOnly"

Seems the NHibernate is doing something somewhere in it's proxy. Does anyone know how to resolve this issue?

Thanks in advance.


What happens if you disable lazy loading on the entity level ? That is, make sure that NHibernate doesn't use dynamic proxies for this class ? (This has no effect on the ability of lazy loading a collection; lazy loading the collection will still work).

In my applications, I use the same approach as the one that you've demonstrated here (private collection field, property that wraps around the collection and returns a readonly list), and I do not have those issues that you're having. But, the difference is that I declare in my mapping ( I do not use fluent NHibernate, but plain old xml files :) ), that NHibernate should not use dynamic proxies for my class:

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


Given that children is a private field, it's not possible for the proxy to be modifying it, as the proxy can only front virtual fields and properties, unless there's some way to set children that isn't in your code. It certainly looks very bizarre, but we would need to see the rest of the class that applies to this.


Your mapping tells nhibernate to use the public Children property, so it won't use the private field "children".

I don't think you can specify private fields in the fluent nhibernate mappings, so if you would want that, you should use an alternative mapping strategy, like xml mapping files.

You can do the following to see if this is indeed the problem:

  • make the "children" field public (for now, just to test it)
  • change the mapping to use the "private" lowercase children field
  • now see if the problem still persists
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜