我在删除具有多对多关系的对象时遇到问题,其中关系作为IDictionary公开,其键是另一个实体(多对多的另一端),值是实例协会班。我想要一个产品对象将所有翻译的标题保存在字典中,这样我就可以在给定文化时获得正确的翻译(即“en-US”)。此外,当我删除产品时,我还想删除所有翻译。我将其设计为单向的,并使用cascade =“all-delete-orphan”,以便在删除产品时删除关联表中的所有记录。通过这里的表,类和映射,我可以获取产品并正确填充其翻译词典。我也可以创建一个带翻译的新产品并保存。但是,我不能做的是删除现有产品(及其翻译)。
首先,表格:
CREATE TABLE Locale (
LocaleId INT NOT NULL IDENTITY PRIMARY KEY,
LanguageCultureCode VARCHAR(16) NOT NULL
)
CREATE TABLE Product (
ProductId INT NOT NULL IDENTITY PRIMARY KEY,
Name VARCHAR(64) NOT NULL
)
CREATE TABLE ProductLocale (
ProductLocaleId INT NOT NULL IDENTITY PRIMARY KEY,
LocaleId INT NOT NULL FOREIGN KEY REFERENCES Locale (LocaleId),
ProductId INT NOT NULL FOREIGN KEY REFERENCES Product (ProductId),
Title NVARCHAR(64)
)
然后是课程:
public class ProductLocale
{
public virtual int Id {get; protected set; }
public string Title {get; set; }
}
public class Locale
{
public virtual int Id { get; protected set; }
public virtual string LanguageCultureCode { get; set; }
}
public class Product
{
public virtual int Id { get; protected set; }
public virtual string Name { get; set; }
public virtual IDictionary<Locale, ProductLocale> Translations { get; protected set; }
接下来,映射:
<class name="ProductLocale">
<id name="Id" column="ProductLocaleId" generator="native" />
<property name="Title" />
</class>
<class name="Locale">
<id name="Id" column="LocaleId" generator="native" />
<property name="LanguageCultureCode" />
</class>
<class name="Product">
<id name="Id" column="ProductId" generator="native" />
<property name="Name" />
<map name="Translations" cascade="all-delete-orphan">
<key column="ProductId" not-null="true" />
<index-many-to-many column="LocaleId" class="Locale" />
<one-to-many class="ProductLocale" />
</map>
</class>
最后,导致异常的代码:
using (var sessionFactory = new Configuration().AddAssembly(Assembly.GetExecutingAssembly()).BuildSessionFactory())
using (var session = sessionFactory.OpenSession())
{
var l = new Locale { LanguageCultureCode = "en-US" };
session.Save(l);
var p = new Product
{
Name = "fate",
Translations =
{ { l, new ProductLocale { Title = "fate" } } }
};
// This is OK.
session.Save(p);
session.Flush();
// This causes a NHibernate.PropertyAccessException
// Exception occurred getter of Locale.Id
// Object does not match target type.
session.Delete(p);
}