NHibernate и LINQ - InvalidOperationException: «Не удалось найти объект с именем ...» - PullRequest
0 голосов
/ 18 ноября 2009

Посмотрите на следующие тесты:

[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.ReadTests.CanReadWithLinq threw исключение: 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 эксп) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.VisitPropertyAccess (PropertyAccessExpression expr) в NHibernate.Linq.Visitors.MemberNameVisitor.VisitPropertyAccess (PropertyAccessExpression expr) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.MemberNameVisitor.GetMemberName (ICriteria rootCriteria, Expression expr) в NHibernate.Linq.Visitors.BinaryCriterionVisitor.VisitPropertyAccess (PropertyAccessExpression expr) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.BinaryCriterionVisitor.GetBinaryCriteria (ICriteria rootCriteria, сеанс ISession, BinaryExpression expr, ComparePropToValue ComparePropToValue, ComparePropToProp сравнитьPropToProp, CompareValueToCriteria compareValueToCriteria, ComparePropToCriteria сравнитьПропоКритерии) в NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitBinaryCriterionExpression (BinaryExpression expr) в NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitBinary (BinaryExpression expr) в NHibernate.Linq.Visitors.ExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.ExpressionVisitor.VisitLambda (LambdaExpression лямбда) в NHibernate.Linq.Visitors.ExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitUnary (УнарноеВыражение expr) в NHibernate.Linq.Visitors.ExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.WhereArgumentsVisitor.GetCriterion (ICriteria rootCriteria, сеанс ISession, Выражение выражение) в NHibernate.Linq.Visitors.RootVisitor.HandleWhereCall (MethodCallExpression позвонить в NHibernate.Linq.Visitors.RootVisitor.VisitMethodCall (MethodCallExpression expr) в NHibernate.Linq.Visitors.ExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit (Expression эксп) в NHibernate.Linq.Visitors.NHibernateQueryTranslator.Translate (Expressionвыражение, QueryOptions queryOptions) в NHibernate.Linq.NHibernateQueryProvider.TranslateExpression (Expression выражение) в NHibernate.Linq.NHibernateQueryProvider.Execute (Expression выражение) в NHibernate.Linq.Query 1.GetEnumerator() at System.Linq.Enumerable.FirstOrDefault<TSource>(IEnumerable 1 источник) в Tests.ReadTests.CanReadWithLinq () в ReadTests.cs: строка 52.

Ответы [ 2 ]

1 голос
/ 19 ноября 2009

Я думаю, что это проблема с файлом отображения XML. Не могли бы вы проверить свой файл Action.hbm.xml, выполнить «F4» и установить «Build Action» на «Embedded Resource».

0 голосов
/ 19 ноября 2009

Решено после извлечения источников 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")]
...