Ошибка «Не сохранять» для NHibernate, NHibernate.Linq и Fluent Mapping - PullRequest
7 голосов
/ 23 января 2010

Я использую Nhibernate 2.1.2.4000 GA с Nhibernate.Linq 1.0 и последней версией FluentNhibernate, загруженной с мастера на github.

Я делаю несколько тестов, и всякий раз, когда я пытаюсь удалить объект, полученный по запросу linq, я получаю эту ошибку:

Не сохранять для: NHibernate.Linq.Query`1 [[Employees.Core.Entities.Employee, Employees.Core, Версия = 1.0.0.0, Культура = нейтральная, PublicKeyToken = null]]

Все остальные операции (вставка, обновление и выбор) выглядят отлично;

Мой класс сущности:

public class Employee
{
    public Employee()
    {
    }

    public virtual Int32 Id { get; private set; }
    public virtual String Name { get; set; }    

    public virtual String SayHello()
    {
        return String.Format("'Hello World!', said {0}.", Name);
    }
}

Класс картирования:

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        Id(x => x.Id);
        Map(x => x.Name)
            .Not.Nullable()
            .Length(50);
    }
}

Конфигурация:

Assembly mappingsAssemly = Assembly.GetExecutingAssembly();

return Fluently.Configure()
    .Database( MsSqlConfiguration.MsSql2008
                    .ConnectionString(connectionString)
                    .ProxyFactoryFactory(typeof(ProxyFactoryFactory))
                    .ShowSql())                            
    .Mappings( m => m.FluentMappings.AddFromAssembly(mappingsAssemly))
    .BuildSessionFactory();

И код, который не работает:

public void RemoveAll()
{
    var q = from employee in _session.Linq<Employee>()
            select employee;

    foreach (var employee in q.ToList())
    {
        _session.Delete(q);
    }
}

Есть мысли?

Ответы [ 3 ]

6 голосов
/ 27 января 2010

Мы все пропустили это!

Извините, ребята, и спасибо за вашу помощь, но я только что понял.

Если вы обратите внимание на метод RemoveAll (), вы увидите, что я пытаюсь удалить объект «q», который не является сущностью, но IQueriable вместо передачи «employee». Это было отсутствие внимания.

Правильный код будет:

        public void RemoveAll()
        {
            var q = from employee in _session.Linq()
                    select employee;

            var p = q.ToList();

            foreach (var employee in p)
            {
                _session.Delete(employee);
            }
        }
2 голосов
/ 23 января 2010

Вы уверены, что сборка, которую вы поставляете в FNH (Assembly.GetExecutingAssembly()), на самом деле содержит ваши сопоставления?

Измените ваш Mappings вызов, включив в него метод ExportTo, который будет экспортировать любые сопоставления, найденные FNH, в указанную папку; проверьте содержимое этой папки и посмотрите, есть ли там все сопоставления. Если это так, то, скорее всего, это не проблема FNH, а проблема с поставщиком Linq (как сказал Майкл).

Mappings(
  m => m.FluentMappings
          .AddFromAssembly(mappingsAssemly)
          .ExportTo(@"C:\"));

Другая вещь, которую вы можете проверить, - это экземпляр конфигурации NHibernate, который NH фактически использует. Для этого используйте BuildConfiguration вместо BuildSessionFactory и проверьте результат; существует коллекция ClassMappings (или ее разновидность), которая должна содержать все сопоставленные сущности.

Если это выглядит нормально, попробуйте создать свой запрос, используя Criteria API или HQL, вместо этого посмотрите, решит ли это вашу проблему (и в этом случае он почти наверняка будет поставщиком linq).

1 голос
/ 23 января 2010

Это может быть просто ошибка в провайдере Linq. Возможно, вы захотите попытаться воспроизвести проблему в отношении последней магистрали NHibernate, в которую входит новый / другой поставщик Linq. В качестве альтернативы, если вы (успешно) удалите Fluent NHibernate из уравнения, вы, вероятно, (относительно легко) отправите тестовый пример / отчет об ошибке провайдеру Linq.

...