2011-10-06 93 views
1

我想使用流利NHibernate。我已經設置了兩個表格產品和類別。 產品具有CategoryID字段和一個將產品的CategoryID與Categories表的PK(CategoryID)關聯的外鍵。Nhibernate試圖添加重複列保存

DTO:產品類別:

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

在我ProductMap課,我有根據流利的文檔,包括設置爲基準的最後一個屬性指定的一切:

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:分類:

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

但是,當我試圖做一個保存在產品實體,我得到一個MySQL錯誤作爲回報,我試圖添加兩次CategoryID。在查看堆棧跟蹤時,它指定了NHibernate試圖保存的列。實際上,它不僅按照我在ProductMap類中指定的順序列出了CategoryID,還要再次作爲插入語句中的最後一列。

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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]"} 

我正在關注作者對Book的例子Fluent的文檔使用。

這幾乎就好像它將Product類的屬性(類型Category)等同於Category表的主鍵。但正如我所提到的,我使用的是Fluent示例代碼中的相同示例。

+0

您能否確定,您沒有將CategoryId映射爲Product中的另一個屬性? –

+0

這是一個流利的錯誤,或者你已經映射了兩次CategoryID。你的對象中有繼承嗎?父類是否有可能映射字段? – Thomas

+0

我已經包含了實際的DTO類和ClassMapping的類以及精確的錯誤以進一步檢查。我仔細檢查過沒有重複的CategoryID映射或其他任何地方。 – pghtech

回答

1

以上回答是正確的。

如果您需要categoryId,請執行Product.Category.Id。

+0

我發現這是正確的。 Fluent/Nhibernate能夠知道在保存新產品實體時將Category.CategoryId放入Products.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的下面生成上面插入:

的CategoryIdCATEGORYID是不一樣的情況。最後注意Idid

+0

謝謝,我會嘗試並更新。有趣的捕獲。我做了一個解決方案廣泛的搜索,沒有這種方式,我的表格也沒有指定這種情況。 – pghtech

0

好吧,如果仔細看看映射,有兩個條目將在db中爲您創建列分類標識。

Map(x => x.CategoryId); 

References(x => x.Category); 

那麼你可以刪除其中的一個,或者如果u需要他們兩個接盤者explcitly像CATEGORY_ID之一的列名。如果它在你的所有引用中是一個普通的東西,那麼就使用一個可以爲你的外鍵關係指定的約定。

另外,如果你看看生成的SQL,你可以看到CategoryIdCateogryid第二個是參考之一。