0

我在尝试使用 Fluent NHibernate 映射实体时遇到了许多问题。

我有三个实体,如下所示:

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 使用 int 作为其 ID,而其他类使用 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。两者一起工作将导致仅创建列。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)第二个问题似乎与 Fluent NHibernate 的约定有些奇怪。我的理解是 ClassMap 的列名应该覆盖约定(这符合逻辑并且更有用)。然而,这似乎并没有发生。该问题可以通过检查约定中的列名是否为空来解决:

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 回答