Exception: Unrecognized method call in expression

84 views
Skip to first unread message

David Campbell

unread,
Sep 14, 2009, 2:23:57 PM9/14/09
to NhLambdaExtensionsUsers
I'm attempting to get objects of one type by filtering on the id of
another. The two types have a many-to-many relationship. These are my
map files:

public TypeAMap()
{
(x => x.TypeAID).GeneratedBy.Identity();
// other mappings ...
HasManyToMany(x => x.GetTypeBs())
.Table("TypeATypeB")
.ParentKeyColumn("TypeAId")
.ChildKeyColumn("TypeBId");
}

public TypeBMap()
{
Id(x => x.TypeBId).GeneratedBy.Identity();
// other mappings ...
}

And my query:

return Session
.CreateCriteria<TypeA>()
.CreateCriteria<TypeA>(a => a.GetTypeBs())
.Add<TypeB>(b => b.TypeBId == selectedTypeBId)
.List<TypeA>();

However when I execute the query, I receive the following error:

System.Exception: Unrecognised method call in epression p.GetTypeBs
()

What am I doing wrong?

Richard Brown (gmail)

unread,
Sep 14, 2009, 2:33:01 PM9/14/09
to NhLambdaExtensionsUsers
Hi David,

I suspect it's the call to GetTypeBs() ... this needs to be the name of the
property (association) defined in the mapping. (I'm not sure how fluentnh
determines this from the mapping example you've supplied.)

.CreateCriteria<TypeA>(a => a.GetTypeBs())

should probably be something like

.CreateCriteria<TypeA>(a => a.BsCollectionProperty)

The collection needs to be publicly exposed to use the extensions, otherwise
you'd need to use regular ICriteria for the .CreateCriteria (using strings).
(And remember you can expose it as IEnumerable is you want to make it
readonly.)

Regards,
Richard


--------------------------------------------------
From: "David Campbell" <david.d....@gmail.com>
Sent: Monday, September 14, 2009 7:23 PM
To: "NhLambdaExtensionsUsers" <nhlambdaext...@googlegroups.com>
Subject: Exception: Unrecognized method call in expression

David D Campbell

unread,
Sep 14, 2009, 3:06:21 PM9/14/09
to nhlambdaext...@googlegroups.com
Thanks. That did the trick.

Stylistically, I prefer to use GetTypeBs() and AddTypeB( TypeB b) methods so that it prevents consumers from blindly setting an entirely new TypeB collection. I can appreciate using IEnumerable to prevent editing the list, but iss there a compromise between which will work yet prevent consumers from completely replacing my collection?

Thanks again.

David

Richard Brown (gmail)

unread,
Sep 14, 2009, 3:13:25 PM9/14/09
to nhlambdaext...@googlegroups.com
Hi David,
 
I agree, you shouldn't expose the collection to external modification, and I too prefer methods like AddTypeB().  You can make the mutator protected, while making the accessor public.  I usually do something like:
 
class A
{
    private IList<B> _bs;
 
    public INumerable<B> Bs
    {
        get { return _bs; }
        protected set { _bs = (IList<B>)value; }           // protects the collection from being externally replaced
    }
}
 
NHibernate (and FluentNH) will happily sail past the protected methods using reflection.
 
Regards,
    Richard

David D Campbell

unread,
Sep 14, 2009, 3:23:09 PM9/14/09
to nhlambdaext...@googlegroups.com
Of course. I should have thought of that. Thanks again!
Reply all
Reply to author
Forward
0 new messages