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.Query1.GetEnumerator() at System.Linq.Enumerable.FirstOrDefault<TSource>(IEnumerable1 источник) в 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".

Другие вопросы по тегам