0

Fluent NHibernate を使用してエンティティをマップしようとすると、多くの問題が発生します。

次のような 3 つのエンティティがあります。

public class Product
{
    public virtual Guid Id { get; set; }
    public virtual Category Category { get; set; }
    public virtual Seller Seller { get; set; }
}

public class Seller
{
    public virtual Guid Id { get; set; }
    public virtual IList<Product> Products { get; set; }
}

public class Category
{
    public virtual int Id { get; set; }
}

Category は ID に int を使用するのに対し、他のクラスは Guid を使用することに注意してください。

私のマッピングクラスは次のようになります。

public sealed class ProductDbMap : ClassMap<Product>
{
    public ProductDbMap()
    {
        Id(x => x.Id);

        References(x => x.Seller)
            .Not.Nullable();

        References(x => x.Category, "Category")
            .Nullable();
    }
}

public sealed class SellerDbMap : ClassMap<Seller>
{
    public SellerDbMap()
    {
        Id(x => x.Id);

        HasMany(x => x.Products);
    }
}

public sealed class CategoryDbMap : ClassMap<Category>
{
    public CategoryDbMap()
    {
        Id(x => x.Id);
    }
}

最後に、参照 ID 列の名前の付け方を指定する次の規則があります。

public class ReferenceConventions : IReferenceConvention
{
    public bool Accept(IManyToOnePart target)
    {
        return true;
    }

    public void Apply(IManyToOnePart target)
    {
        target.ColumnName(target.Property.Name + "Id");
    }
}

NHibernate がテーブルの生成を決定する方法は次のとおりです。

create table Product (
   Id UNIQUEIDENTIFIER not null,
   SellerId UNIQUEIDENTIFIER not null,
   CategoryId INTEGER,
   Seller_id UNIQUEIDENTIFIER,
   primary key (Id)
)

create table Seller (
   Id UNIQUEIDENTIFIER not null,
   primary key (Id)
)

create table Category (
   Id  integer,
   primary key (Id)
)

Product テーブルの生成にはいくつかのエラーがあります。

  1. 「SellerId」列が何らかの理由で重複しています。重複する列は私の命名規則に従っていません。
  2. References メソッドに「Category」の値を指定して、「CategoryId」列の命名規則をオーバーライドしようとしています。ただし、テーブルでは代わりに規則が引き続き使用されます。

何が起こっている?

4

1 に答える 1

2

ここで自分の質問に答えます。

1) ReferenceConvention に加えて HasManyConvention を追加する必要があるため、重複した列が発生します。2 つが連携すると、列のみが作成されます。HasManyConvention のコードは次のとおりです。

public class HasManyConventions : IHasManyConvention
{
    public bool Accept(IOneToManyPart target)
    {
        return true;
    }

    public void Apply(IOneToManyPart target)
    {
        target.KeyColumnNames.Add(target.EntityType.Name + "Id");
    }
}

2) 2 番目の問題は、Fluent NHibernate の慣習に奇妙な点があるようです。ClassMap の列名が規則をオーバーライドする必要があることを理解していました (これは論理的に意味があり、より便利です)。ただし、これは発生していないようです。この問題は、規則で列名が null かどうかを確認することで解決できます。

public class ReferenceConventions : IReferenceConvention
{
    public bool Accept(IManyToOnePart target)
    {
        return true;
    }

    public void Apply(IManyToOnePart target)
    {
        if (target.GetColumnName() == null)
            target.ColumnName(target.Property.Name + "Id");
    }
}
于 2009-09-09T04:38:15.093 に答える