Проблема с беглым автоматическим сопоставлением Nhibernate и Guids / UniqueIdentifiers в качестве полей первичного ключа - PullRequest
1 голос
/ 01 сентября 2009

Я пытаюсь использовать функцию автоматического определения 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();
    }
}

Кроме того, если я отключу автоматическое отображение и использую настроенную карту, таблицы будут сгенерированы успешно.

Это сводит меня с ума, и я уверен, что это, вероятно, быстрое решение. Есть идеи?

Спасибо!

Anthony

1 Ответ

4 голосов
/ 14 сентября 2009

Видимо, возникла проблема в Fluent Nhibernate версии 1.0RC и версии 1.0. Однако, если вы загружаете последнюю версию из ствола SVN, все работает отлично. Похоже, что проблема была просто ошибка в коде, который теперь был исправлен.

Кроме того, я должен отметить, что Джеймс Грегори, Пол Батум и, возможно, другие, активно работают над Fluent NHibernate. Продукт развивается довольно резко, и за последние пару месяцев в коде произошли значительные изменения.

...