views:

230

answers:

2

Have a look at the following tests:

[TestMethod]
public void CanRead()
{
    using (ISession session = OpenSession())
    {
     var criteria = session.CreateCriteria(typeof(Action));
     var result = criteria.List<Action>();
     Assert.IsTrue(result.Count > 0);
    }
}

[TestMethod]
public void CanReadWithLinq()
{
    using (ISession session = OpenSession())
    {
     IEnumerable<Action> actionQuery = from action in session.Linq<Action>() 
               where action.CreatedOn < DateTime.Now
               select action;
     List<Action> actions = actionQuery.ToList();
     Assert.IsNotNull(actions);
     Assert.IsTrue(actions.Count > 0);
    }
}

First one runs, so I assume that the mapping is correct (using NHibernate.Attributes in the Action class). Test two fails with the exception:

System.InvalidOperationException: Could not find entity named: BOM.Domain.Action.

It turns out, that every linq expression that uses the entity in the where condition fails with this exception. Removing the where will make it pass, but this is not what I want to achieve, of course. What am I missing? Why is there this exception?


Update:

I created a separate project as follows.

The domain object:

namespace Domain
{
    public class TestEntity
    {
        public Guid Id { get; set; }
        public DateTime CreatedOn { get; set; }
    }
}

The mapping document:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class entity-name="T_TestEntity" name="Domain.TestEntity, Domain" lazy="false">
    <id name="Id" />
    <property name="CreatedOn" column="CreatedOn" />
  </class>
</hibernate-mapping>

Unit test initialization creates a SQL CE database file, which looks to be fine. Tests are quite similar, and I've got the same behavior as before: The fetching with ICriteria works fine, the fetching with Linq works fine until I add a condition that is related to the domain object. Same InvalidOperationException as before, here the stack trace:

Test method Tests.ReadTests.CanReadWithLinq threw exception: System.InvalidOperationException: Could not find entity named: Domain.TestEntity. at NHibernate.Linq.Util.CriteriaUtil.GetRootType(CriteriaImpl criteria) at NHibernate.Linq.Util.CriteriaUtil.GetRootType(ICriteria criteria) at NHibernate.Linq.Visitors.MemberNameVisitor.IsRootEntity(EntityExpression expr) at NHibernate.Linq.Visitors.MemberNameVisitor.VisitEntity(EntityExpression expr) at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.VisitPropertyAccess(PropertyAccessExpression expr) at NHibernate.Linq.Visitors.MemberNameVisitor.VisitPropertyAccess(PropertyAccessExpression expr) at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.MemberNameVisitor.GetMemberName(ICriteria rootCriteria, Expression expr) at NHibernate.Linq.Visitors.BinaryCriterionVisitor.VisitPropertyAccess(PropertyAccessExpression expr) at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.BinaryCriterionVisitor.GetBinaryCriteria(ICriteria rootCriteria, ISession session, BinaryExpression expr, ComparePropToValue comparePropToValue, ComparePropToProp comparePropToProp, CompareValueToCriteria compareValueToCriteria, ComparePropToCriteria comparePropToCriteria) at NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitBinaryCriterionExpression(BinaryExpression expr) at NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitBinary(BinaryExpression expr) at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.ExpressionVisitor.VisitLambda(LambdaExpression lambda) at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitUnary(UnaryExpression expr) at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.WhereArgumentsVisitor.GetCriterion(ICriteria rootCriteria, ISession session, Expression expression) at NHibernate.Linq.Visitors.RootVisitor.HandleWhereCall(MethodCallExpression call) at NHibernate.Linq.Visitors.RootVisitor.VisitMethodCall(MethodCallExpression expr) at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp) at NHibernate.Linq.Visitors.NHibernateQueryTranslator.Translate(Expression expression, QueryOptions queryOptions) at NHibernate.Linq.NHibernateQueryProvider.TranslateExpression(Expression expression) at NHibernate.Linq.NHibernateQueryProvider.Execute(Expression expression) at NHibernate.Linq.Query1.GetEnumerator() at System.Linq.Enumerable.FirstOrDefault<TSource>(IEnumerable1 source) at Tests.ReadTests.CanReadWithLinq() in ReadTests.cs: line 52.

+1  A: 

I think it's a problem with the XML mapping file. Could you check your file Action.hbm.xml, do "F4" and set "Build Action" to "Embedded Resource".

Kris-I
This is not the problem. I am using NHibernate.Attributes and create the mapping document on thy fly. Moreover, if this would be the problem, the other test would not pass.However, even when using the static mapping xml the same problem persists.
Marc Wittke
A: 

Solved it after fetching the NHibernate and NHibernate Contrib sources and stepping through: I have to provide the entity name from the database when creating the INHibernateQueryable.

IEnumerable<TestEntity> query = from testEntity in session.Linq<TestEntity>("T_TestEntity") 
    where testEntity.CreatedOn < DateTime.Now
    select testEntity;

I'm still unsure if this is the final solution.


Update

The mapping document defined the entity name instead of the table name. This resulted in a correct schema when exporting and it was also capable of handling the existing schema. However, it behaves different wwith Linq. The correct mapping definition would be:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class table="T_TestEntity" name="Domain.TestEntity, Domain">
    <id name="Id" />
    <property name="CreatedOn" column="CreatedOn" />
  </class>
</hibernate-mapping>

or (when using the attribute mapping of NHibernate Contrib):

[Class(Name = "Domain.TestEntity, Domain", Table = "T_TestEntity")]
Marc Wittke