1

Fluent-NHibernate 自動マッピング機能 (最新バージョンのソフトウェア) を使用しようとしていますが、主キー フィールドとして Guid を使用すると問題が発生します。主キーに整数フィールドを使用すると、テーブルが正常に生成され、すべての 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();
    }
}

また、自動マッピングをオフにして流暢に構成されたマップを使用すると、テーブルが正常に生成されます。

これは私を狂わせており、おそらく簡単な修正だと確信しています。何か案は?

ありがとうございました!

アンソニー

4

1 に答える 1

4

どうやら、Fluent Nhibernate バージョン 1.0RC およびバージョン 1.0 に問題があったようです。ただし、SVN トランクから最新バージョンをダウンロードすると、すべてが完全に機能します。問題は単にコードのバグだったようで、現在は修正されています。

また、James Gregory、Paul Batum、およびおそらく他の人々が Fluent NHibernate に積極的に取り組んでいることにも注意してください。この製品はかなり劇的に進化しており、ここ数か月でコードに大幅な変更が加えられました。

于 2009-09-14T07:54:25.473 に答える