NHibernate и LINQ - InvalidOperationException: "Не удалось найти объект с именем..."
Посмотрите на следующие тесты:
[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);
}
}
Сначала выполняется, поэтому я предполагаю, что сопоставление является правильным (с помощью NHibernate.Attributes в Action
учебный класс). Тест два не проходит с исключением:
System.InvalidOperationException: Не удалось найти объект с именем: BOM.Domain.Action.
Оказывается, что каждое выражение 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.Read Tests.CanReadWithLinq вызвал исключение: System.InvalidOperationException: Не удалось найти объект с именем: Domain.TestEntity. в NHibernate.Linq.Util.CriteriaUtil.GetRootType(критерии CriteriaImpl) в NHibernate.Linq.Util.CriteriaUtil.GetRootType(критерии ICriteria) в NHibernate.Linq.Visitors.MemberNameVisitor.IsRootEgitExinE ВыражениеВыражениеВыражениеВыражениеВыраженияВыраженияПредставителей.VisitEntity (выражение EntityExpression) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(выражение выражения) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.VisitPropertyAccess (выражение свойства PropertyExccess.Exception..Linq.Visitors. NHibernateExpressionVisitor.Visit (Expression exp) в NHibernate.Linq.Visitors.BinaryCriterionVisitor.GetB inaryCriteria (ICriteria rootCriteria, ISession сессия, BinaryExpression выражение, ComparePropToValue comparePropToValue, ComparePropToProp comparePropToProp, CompareValueToCriteria compareValueToCriteria, ComparePropToCriteria comparePropToCriteria) при NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitBinaryCriterionExpression(BinaryExpression ехрг) при NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitBinary(BinaryExpression выражение.ExpressionVisitor.Visit(выражение Expression) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(выражение Expression) в NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitUnary(выражение UnaryExpression) в выражении NHibernate.Linq.Visitor. NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp) в NHibernate.Linq.Visitors.WhereArgumentsVisitor.GetCriterion(ICriteria rootCriteria, сеанс ISession, выражение Expression) в NHibernate.Linq.Visitors.RootVisitor.HandleWhereCall.Ogn.Visis. VisitMethodCall (выражение Expression Explay) в NHibernate.Linq.Visitors.ExpressionVisitor.Visit(выражение Expression) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor (Expression exp) в выражении выражения NHibernate.Linq.Visitors.NHeries в NHibernate.Linq.NHibernateQueryProvider.TranslateExpression (выражение выражения) в NHibernate.Linq.NHibernateQueryProvider.Execute (выражение выражения) в NHibernate.Linq.Query
1.GetEnumerator() at System.Linq.Enumerable.FirstOrDefault<TSource>(IEnumerable
1 источник) в Tests.ReadTests.CanReadWithLinq() в ReadTests.cs: строка 52.
2 ответа
Решил это после извлечения источников 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")]
Я думаю, что это проблема с файлом сопоставления XML. Не могли бы вы проверить свой файл Action.hbm.xml, выполнить "F4" и установить "Build Action" в "Embedded Resource".