2011-10-06 49 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第二个是参考之一。