views:

34

answers:

1

Hi, my application has the following entity:

public class User
{
    public virtual int UserID { get; set; }
    public virtual Membership LatestMembership { get { return Membership.First(); } }
    public virtual IList<Membership> Membership { get; set; }

    public User()
    {
        Membership = new List<Membership>();
    }
}

With the following mapping:

public UserMap()
{
    Table("Users");
    Id(x => x.UserID);
    HasMany(x => x.Membership)
        .KeyColumn("UserID")
        .OrderBy("DateAdded DESC")
        .Inverse()
        .Cascade.All();
}

The LatestMembership property against the user simply grabs the first record from the Membership collection (which is ordered so that the newer records are at the top).

So far so good, however now say i want to do the following (i know this will return them all but i'm just using this as an example):

var users = session.Linq<User>()
    .Where(u => u.LatestMembership.DateAdded < DateTime.UtcNow);

An error is thrown because the LatestMembership property is beyond the nhibernate linq providers capabilities. The only solution i have so far is to convert it to a list and then apply the where condition but i'd imagine this could become pretty insuficient for a large database.

I was wondering if there was an alternative way i could map this or what your recommendations are. Thanks

+1  A: 

Unfortunately, this isn't really possible using the current Linq provider. One thing you can do is to map the properties of the LatestMembership you want to query on as read-only and use formulas in your mappings to derive the values for it. You can see some further details in my answer to this post.

The other possible solution is to attack this from the Membership side of things; query for the latest membership matching the user in question and filter accordingly.

DanP
Hi, i've used formulas in the past to map to a string, bool or int but mapping to the Membership object is beyond me. I did think about attacking this from the Membership side but the query gets a little complicated. Say if i try:var users = session.Linq<Membership>().Where(m => m.DateAdded < DateTime.UtcNow).Select(m => m.User).Distinct().Basically it grabs all the membership filters it then does a distinct to get the unique users. The problem though is that it's not querying the latest membership for the user and i can't see how to do it.
nfplee
You won't be able to map the actual membership object using a formula; but you could potentially map its properties that you want to query on using one...
DanP
Cheers i'm not quite keen on this approach so i'll probably have to keep doing what i am for now.
nfplee