Проблема с плавным автоматическим отображением Nhibernate и идентификаторами Guids / UniqueIdentifiers в качестве полей первичного ключа
Я пытаюсь использовать функциональность автоматического определения Fluent-NHibernate (в последней версии программного обеспечения) и сталкиваюсь с проблемами, используя Guids в качестве полей первичного ключа. Если я использую целочисленные поля для первичных ключей, таблицы генерируются успешно, и кажется, что все функции Nhibernate работают нормально. К вашему сведению, я использую NHibernate для генерации таблиц базы данных.
Вот пара классов с целочисленными идентификаторами.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
namespace Sample.Data.Entities
{
public class Employee
{
public virtual int Id { get; private set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual Store Store { get; set; }
}
public class Product
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual double Price { get; set; }
public virtual IList<Store> StoresStockedIn { get; private set; }
public Product()
{
StoresStockedIn = new List<Store>();
}
}
public class Store
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
public virtual IList<Employee> Staff { get; set; }
public Store()
{
Products = new List<Product>();
Staff = new List<Employee>();
}
public virtual void AddProduct(Product product)
{
product.StoresStockedIn.Add(this);
Products.Add(product);
}
public virtual void AddEmployee(Employee employee)
{
employee.Store = this;
Staff.Add(employee);
}
}
}
Вот те же классы с GUID.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
namespace Sample.Data.Entities
{
public class Employee
{
public virtual Guid Id { get; private set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual Store Store { get; set; }
}
public class Product
{
public virtual Guid Id { get; private set; }
public virtual string Name { get; set; }
public virtual double Price { get; set; }
public virtual IList<Store> StoresStockedIn { get; private set; }
public Product()
{
StoresStockedIn = new List<Store>();
}
}
public class Store
{
public virtual Guid Id { get; private set; }
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
public virtual IList<Employee> Staff { get; set; }
public Store()
{
Products = new List<Product>();
Staff = new List<Employee>();
}
public virtual void AddProduct(Product product)
{
product.StoresStockedIn.Add(this);
Products.Add(product);
}
public virtual void AddEmployee(Employee employee)
{
employee.Store = this;
Staff.Add(employee);
}
}
}
Вот моя конфигурация.
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.FromConnectionStringWithKey("AAAConnectionString"))
.UseReflectionOptimizer()
.AdoNetBatchSize(25)
.DefaultSchema("dbo")
.Cache(c => c
.UseQueryCache()
.ProviderClass<HashtableCacheProvider>())
.ShowSql())
.Mappings(m=>m.AutoMappings
.Add(AutoMap.AssemblyOf<Sample.Data.Entities.Product>()
.Where(type => type.Namespace == "Sample.Data.Entities.Product")
.Conventions.AddFromAssemblyOf<Sample.Data.Fluent.Conventions.PrimaryKeyNameConvention>()
))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
Чтобы обойти эту проблему, я попытался сгенерировать соглашения (см. Ниже) для 1), назвав поле Id (хотя я думал, что это должно было быть ненужным), и для 2), создав Id (который, я думал, был бы автоматическим). Я не уверен, что происходит или почему это не работает.
public class PrimaryKeyNameConvention : IIdConvention
{
public bool Accept(IIdentityInstance id)
{
return true;
}
public void Apply(IIdentityInstance id)
{
id.Column("Id");
}
}
public class PrimaryKeyGeneratorConvention : IIdConvention
{
public bool Accept(IIdentityInstance id)
{
return true;
}
public void Apply(IIdentityInstance id)
{
id.GeneratedBy.GuidComb();
}
}
Кроме того, если я отключу автоматическое отображение и использую настроенную карту, таблицы будут сгенерированы успешно.
Это сводит меня с ума, и я уверен, что это, вероятно, быстрое решение. Есть идеи?
Спасибо!
Энтони
1 ответ
По-видимому, была проблема в Fluent Nhibernate версии 1.0RC и версии 1.0. Однако, если вы загрузите последнюю версию из ствола SVN, все работает отлично. Похоже, что проблема была просто ошибка в коде, который теперь был исправлен.
Кроме того, я должен отметить, что Джеймс Грегори, Пол Батум и, возможно, другие, активно работают над Fluent NHibernate. Продукт развивается довольно резко, и за последние пару месяцев в коде произошли значительные изменения.