0

Guys,

I've got this problem that I searched almost everywhere (maybe I don't know the right keyword for it.) I need your help!

The relationship is quite simple, I have two Activerecord Domain: Team and User, and they have HasAndBelongsToMany relationship to each other.

My requirement now is to query the count of Users which has Team.Id = 4 and query the list of Users which has Team.Id = 4. So I am doing something like:

DetachedCriteria c = DetachedCriteria.For<Models.User>()
            .AddOrder(Order.Desc("RegisterTime"))
            .CreateAlias("Teams", "teams")
            .Add(Expression.Eq("teams.Id", 4));

int count = ActiveRecordMediator<Models.User>.Count(c);
IList<Models.User> users = Models.User.FindAll(c); 

Count is correctly retrieved, but the for the List query, I get exception:

Exception Details: System.InvalidCastException: At least one element in the source array could not be cast down to the destination array type.

If I use them separately. They are both correct. But when I use them one after another. There comes the exception. It's like DetachedCriteria shall not be used closely in two queries. Why is that?

What's the correct way to do it?

Need your help!

larryzhao
  • 3,173
  • 2
  • 40
  • 62

2 Answers2

1

I found a way to do it, although I am still not clear about the root cause, but writing the code like following makes it right and also looks good:

DetachedCriteria c = DetachedCriteria.For<Models.User>().AddOrder(Order.Desc("RegisterTime")).CreateAlias("Teams", "teams").Add(Expression.Eq("teams.Id", 4));
int count = ActiveRecordMediator<Models.User>.Count(NHibernate.CriteriaTransformer.TransformToRowCount(c));
IList<Models.User> users = Models.User.FindAll(c);

I answered my own question just to put this approach here, I am not sure about if this is the best answer for it.

And I am eager to hear more on this!

larryzhao
  • 3,173
  • 2
  • 40
  • 62
0

my bet would be ActiveRecordMediator<Models.User>.Count(c); alters the criteria with a projection which will result in the exception in the second call. You can work around this with cloning the criteria for each query.

var clonedcrit = NHibernate.CriteriaTransformer.Clone(c)
Firo
  • 30,626
  • 4
  • 55
  • 94
  • I see something like this here: http://roytate.blogspot.com/2007/03/castle-activerecord-with.html, in this post, Roy used CountQuery, which looks quite nice, and called dc.SetProjection(null) before call SlicedFindAll(). I tried Roy's approach, it failed. – larryzhao Jul 18 '11 at 16:55
  • I just tried your solution. Use the clonedcrit for the second call, it failed, either..why is that...? – larryzhao Jul 18 '11 at 16:55
  • @larryzhao have you cloned it befor the call to count? – Firo Jul 19 '11 at 07:31
  • I tried it again. It works. Maybe I messed something up at first. This is good. – larryzhao Jul 19 '11 at 16:29