使用流畅的Nhibernate Automapping和Guids / UniqueIdentifier作为主键字段的问题

时间:2009-09-01 01:31:55

标签: nhibernate fluent-nhibernate automapping fluent-interface

我正在尝试使用Fluent-NHibernate自动化功能(在最新版本的软件中),并且使用Guids作为主键字段时遇到了问题。如果我对主键使用整数字段,则会成功生成表,并且所有Nhibernate功能似乎都能正常工作。仅供参考,我正在使用NHibernate生成我的数据库表。

以下是几个带有整数ID的类。

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();
    }
}

此外,如果我关闭自动关闭并使用Fluently配置的地图,则表格会成功生成。

这让我疯了,我相信这可能是一个快速解决方案。有任何想法吗?

谢谢!

安东尼

1 个答案:

答案 0 :(得分:4)

显然,Fluent Nhibernate版本1.0RC和版本1.0存在问题。但是,如果从SVN主干下载最新版本,那么每件事都可以完美运行。似乎问题只是代码中的一个错误,现在已经得到纠正。

另外,我应该注意到James Gregory,Paul Batum和其他人正在积极研究Fluent NHibernate。该产品发展非常迅速,并且在过去几个月中代码发生了重大变化。