Nhibernate尝试在保存时添加重复列
本文关键字:添加 保存 Nhibernate | 更新日期: 2023-09-27 18:10:31
我正在尝试使用Fluent NHibernate。我已经设置了两个表产品和类别。Products有一个CategoryID字段和一个外键,将Products的CategoryID绑定到Categories表的PK (CategoryID)。
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类中,我有一个根据Fluent文档指定的一切,包括最后一个属性设置为引用:
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: Category:
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);
}
}
然而,当我尝试对Product实体进行保存时,我得到一个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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]"}
我正在遵循Fluent文档使用的作者到Book示例。
就好像它将Product类上的属性(类型Category)等同于Category表的主键。但正如我提到的,我使用的是来自Fluent示例代码的相同示例。
以上答案是正确的。
如果您需要categoryId,则执行Product.Category.Id。
我会尝试在映射中指定列名:
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生成的insert中有以下内容:
CategoryId和CategoryId不是同一种情况。注意末尾的Id
和id
如果您仔细查看映射,会发现有两个条目将在db中为您创建列categoryid。
Map(x => x.CategoryId);
References(x => x.Category);
你可以删除其中一个,或者如果你需要它们,那么设置其中一个的列名显式地像category_id。如果它在你所有的引用中都是通用的,那么使用一个你可以为你的外键关系指定的约定。
如果您查看生成的sql,您可以看到CategoryId
和Cateogryid
,第二个是参考的一个。