2011-10-06 5 views
1

Fluent NHibernateを使用しようとしています。私は2つの表の製品とカテゴリを設定しています。 製品にはCategoryIDフィールドと、ProductsのCategoryIDをCategoriesテーブルのPK(CategoryID)に結び付ける外部キーがあります。Nhibernateが保存時に重複カラムを追加しようとしています

DTO:製品のクラス:

public class ProductMap : ClassMap<Product> 
{ 
    public ProductMap() 
    { 
     Table("Products"); 
     Id(x => x.ProductId); 
     Map(x => x.Name); 
     Map(x => x.CategoryId); 
     Map(x => x.Description); 
     Map(x => x.Price); 
     Map(x => x.SalePrice); 
     Map(x => x.StockAmt); 
     Map(x => x.StockLevelWarning); 
     Map(x => x.Dimensions); 
     Map(x => x.PriceIncludesTax); 
     Map(x => x.TaxClass); 
     Map(x => x.ProductWeight); 
     Map(x => x.CubicWeight); 
     Map(x => x.PackageDimensions); 
     Map(x => x.IncludeLatestProduct); 
     References(x => x.Category); 
    } 
} 

DTO:私のProductMapクラスで

public class Product 
{ 
    [HiddenInput(DisplayValue = false)] 
    public virtual int ProductId { get; set; } 
    public virtual string Name { get; set; } 
    public virtual int CategoryId { get; set; } 

    [DataType(DataType.MultilineText)] 
    public virtual string Description { get; set; } 
    public virtual decimal Price { get; set; } 
    public virtual decimal SalePrice { get; set; } 
    public virtual int StockAmt { get; set; } 
    public virtual bool StockLevelWarning { get; set; } 
    public virtual string Dimensions { get; set; } 
    public virtual bool PriceIncludesTax { get; set; } 
    public virtual string TaxClass { get; set; } 
    public virtual decimal ProductWeight { get; set; } 
    public virtual decimal CubicWeight { get; set; } 
    public virtual string PackageDimensions { get; set; } 
    public virtual bool IncludeLatestProduct { get; set; } 
    public virtual Category Category { get; set; } 

    public Product() 
    { 
     Name = String.Empty; 
     Description = String.Empty; 
     Price = 0m; 
     SalePrice = 0m; 
     StockAmt = 0; 
     StockLevelWarning = true; 
     Dimensions = String.Empty; 
     PriceIncludesTax = false; 
     TaxClass = String.Empty; 
     ProductWeight = 0; 
     CubicWeight = 0; 
     PackageDimensions = String.Empty; 
     IncludeLatestProduct = false; 
    } 
} 

、私はリファレンスとして設定された最後のプロパティを含む流暢マニュアルに従って、指定されたすべてのものを持っています:カテゴリ:

public class Category 
{ 
    public virtual int CategoryId { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 
    public virtual IList<Product> Products { get; set; } 

    public Category() 
    { 
     Name = string.Empty; 
     Description = string.Empty; 
    } 
} 



public class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Table("Categories"); 
     Id(x => x.CategoryId); 
     Map(x => x.Name); 
     Map(x => x.Description).Column("CategoryDescription"); 
     HasMany(x => x.Products); 
    } 
} 

ただし、製品を保存しようとするとエンティティ、私はCategoryIDを2回追加しようとしているという返答でMySQLエラーが発生します。スタックトレースを見ると、NHibernateが保存しようとしているカラムを指定します。実際、ProductMapクラスで指定した順序でCategoryIDだけでなく、insertステートメントの最後の列としてリストされます。

Error: 
    "could not insert: [DTOS.Product][SQL: INSERT INTO Products (Name, CategoryId, Description, Price, SalePrice, StockAmt, StockLevelWarning, Dimensions, PriceIncludesTax, TaxClass, ProductWeight, CubicWeight, PackageDimensions, IncludeLatestProduct, Categoryid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]"} 

私はFluentのドキュメンテーションの使用例に従っています。

それがカテゴリテーブルの主キーにProductクラスに(タイプカテゴリ)プロパティを等しくするされているかのようにそれはほとんどです。しかし、私が言及したように、私はFluentのサンプルコードから同じ例を使用しています。

+0

CategoryIdをProductの別のプロパティとしてマップしていないことを確認できますか? –

+0

これはFluentバグであるか、CategoryIDを2度マッピングしたものです。あなたはあなたの物にいかなる相続物も持っていますか?親クラスもフィールドをマップしている可能性はありますか? – Thomas

+0

私は実際のDTOクラスとClassMappingのクラスと正確なエラーをより詳細に検査するために含めました。私は、CategoryIDマッピングや他の場所の重複がないことを二重チェックしました。 – pghtech

答えて

1

上記の回答は正しいです。

あなたは区分が必要な場合は、その後Product.Category.Idを行います。

+0

これは正しいことがわかりました。 Fluent/Nhibernateが、新しい製品エンティティを保存するときに、Products.CategoryIdフィールドにCategory.CategoryIdを入れることを知ることができるという神秘的な能力には少しぼやけています。 – pghtech

0

私はあなたのマッピングで列名を指定しようとするだろう:

public class ProductMap : ClassMap<Product> 
{ 
    public ProductMap() 
    { 
     Table("Products"); 
     Id(x => x.ProductId); 
     References(x => x.Category).Column("CategoryId"); 
    } 
} 

public class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Table("Categories"); 
     Id(x => x.CategoryId); 
     HasMany(x => x.Products).KeyColumn("ProductId"); 
    } 
} 

私はNHibernateの中で次のように気づい上記挿入生成:

区分区分同じケースではありません。最後にIdidに注目してください。

+0

ありがとう、私はそれを試して更新します。面白いキャッチ。私はソリューション全体の検索を行い、そのように扱われていないし、私のテーブルはそのようにケースを指定していません。 – pghtech

0

よくマッピングを見ると、データベースにcategoryid列が作成される2つのエントリがあります。

Map(x => x.CategoryId); 

References(x => x.Category); 

さて、あなたがそれらのいずれかを削除するか、uはそれらの両方を必要とするならば、CATEGORY_IDのようなものをexplcitlyなものの一つの列名を設定することができます。あなたのすべての参照を渡ってその一般的なものが次にあなたの外来のキーの関係のために指定することができる規則を使用する場合。

また、生成されたSQLを見ると、CategoryIdCateogryidが参照されています。