NHibernate和LINQ - InvalidOperationException:“找不到名为...的实体”

时间:2009-11-18 13:27:01

标签: linq nhibernate linq-to-nhibernate

看看以下测试:

[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);
    }
}

第一个运行,所以我假设映射是正确的(使用Action类中的NHibernate.Attributes)。测试2失败,例外:

  

System.InvalidOperationException:   找不到名为的实体:   BOM.Domain.Action。

事实证明,在where条件中使用实体的每个linq表达式都会因此异常而失败。删除它将使它通过,但当然这不是我想要实现的。我错过了什么?为什么会有这个例外?


更新

我创建了一个单独的项目如下。

域对象:

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

地图文档:

<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>

单元测试初始化​​会创建一个SQL CE数据库文件,看起来没问题。测试非常相似,我有与以前相同的行为:使用ICriteria获取工作正常,使用Linq获取工作正常,直到我添加与域对象相关的条件。与之前相同的InvalidOperationException,这里是堆栈跟踪:

  

测试方法Tests.ReadTests.CanReadWithLinq扔了   例外:   System.InvalidOperationException:   找不到名为的实体:   Domain.TestEntity。在   NHibernate.Linq.Util.CriteriaUtil.GetRootType(CriteriaImpl   标准)   NHibernate.Linq.Util.CriteriaUtil.GetRootType(的ICriteria   标准)   NHibernate.Linq.Visitors.MemberNameVisitor.IsRootEntity(EntityExpression   expr)at   NHibernate.Linq.Visitors.MemberNameVisitor.VisitEntity(EntityExpression   expr)at   NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(表达式   exp)at   NHibernate.Linq.Visitors.NHibernateExpressionVisitor.VisitPropertyAccess(PropertyAccessExpression   expr)at   NHibernate.Linq.Visitors.MemberNameVisitor.VisitPropertyAccess(PropertyAccessExpression   expr)at   NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(表达式   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(表达式   exp)at   NHibernate.Linq.Visitors.BinaryCriterionVisitor.GetBinaryCriteria(的ICriteria   rootCriteria,ISession会话,   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(表达式   exp)at   NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(表达式   exp)at   NHibernate.Linq.Visitors.ExpressionVisitor.VisitLambda(LambdaExpression   lambda)   NHibernate.Linq.Visitors.ExpressionVisitor.Visit(表达式   exp)at   NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(表达式   exp)at   NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitUnary(UnaryExpression   expr)at   NHibernate.Linq.Visitors.ExpressionVisitor.Visit(表达式   exp)at   NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(表达式   exp)at   NHibernate.Linq.Visitors.WhereArgumentsVisitor.GetCriterion(的ICriteria   rootCriteria,ISession会话,   表达式)   NHibernate.Linq.Visitors.RootVisitor.HandleWhereCall(MethodCallExpression   打电话给   NHibernate.Linq.Visitors.RootVisitor.VisitMethodCall(MethodCallExpression   expr)at   NHibernate.Linq.Visitors.ExpressionVisitor.Visit(表达式   exp)at   NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(表达式   exp)at   NHibernate.Linq.Visitors.NHibernateQueryTranslator.Translate(表达式   表达式,QueryOptions queryOptions)   在   NHibernate.Linq.NHibernateQueryProvider.TranslateExpression(表达式   表达)at   NHibernate.Linq.NHibernateQueryProvider.Execute(表达式   表达)at   NHibernate.Linq.Query 1.GetEnumerator() at System.Linq.Enumerable.FirstOrDefault<TSource>(IEnumerable 1   来源)   Tests.ReadTests.CanReadWithLinq()in   ReadTests.cs:第52行。

2 个答案:

答案 0 :(得分:1)

我认为这是XML映射文件的问题。你能检查你的文件Action.hbm.xml,做“F4”并将“Build Action”设置为“Embedded Resource”。

答案 1 :(得分:0)

在获取NHibernate和NHibernate Contrib源并逐步完成后解决了这个问题:我必须在创建INHibernateQueryable时从数据库中提供实体名称。

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

我仍然不确定这是否是最终解决方案。


更新

映射文档定义了实体名称而不是表名。这导致导出时的正确模式,并且它还能够处理现有模式。然而,它与Linq的行为不同。正确的映射定义是:

<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>

或(当使用NHibernate Contrib的属性映射时):

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