NHibernate and LINQ - InvalidOperationException: "Could not find entity named ..."
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开发者_JAVA技巧: 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.Query
1.GetEnumerator() at System.Linq.Enumerable.FirstOrDefault<TSource>(IEnumerable
1 source) at Tests.ReadTests.CanReadWithLinq() in ReadTests.cs: line 52.
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".
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")]
精彩评论