0

看看以下测试:

[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)。测试二失败,但有以下例外:

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

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


更新:

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

域对象:

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) 在 NHibernate.Linq.Visitors.MemberNameVisitor .VisitEntity(EntityExpression expr) 在 NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp) 在 NHibernate.Linq.Visitors.NHibernateExpressionVisitor.VisitPropertyAccess(PropertyAccessExpression expr) 在 NHibernate.Linq.Visitors.MemberNameVisitor.VisitPropertyAccess(PropertyAccessExpression) 在 NHibernate .Linq.Visitors.NHibernateExpressionVisitor。1.GetEnumerator() at System.Linq.Enumerable.FirstOrDefault<TSource>(IEnumerable1 来源)在 ReadTests.cs 中的 Tests.ReadTests.CanReadWithLinq():第 52 行。

4

2 回答 2

1

我认为这是 XML 映射文件的问题。您能否检查您的文件 Action.hbm.xml,执行“F4”并将“构建操作”设置为“嵌入式资源”。

于 2009-11-19T07:54:57.877 回答
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")]
于 2009-11-19T09:23:50.117 回答