看看以下测试:
[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行。
答案 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")]