使用FluentNhibernate;
我试图坚持一个看似简单的对象模型:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public Config Config { get; set; }
}
public class Config
{
public int ConfigId { get; set; }
public int ProductId { get; set; }
public string ConfigField1 { get; set; }
public string ConfigField2 { get; set; }
}
并且数据库看起来像:(在语法上不正确)
CREATE TABLE [dbo].[Products](
[ProductId] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NULL
)
CREATE TABLE [dbo].[Config](
[ConfigId] [int] IDENTITY(1,1) NOT NULL,
[ProductId] [int] NOT NULL,
[ConfigField1] [varchar](50) NULL,
[ConfigField2] [varchar](50) NULL
) ON [PRIMARY]
开箱即用的fluent-nhibernate将尝试将其映射为Products
表上的外键,例如:
INSERT INTO Products(Name,Config_id)VALUES(?,?);
我不希望它这样做,而是我希望映射会首先插入Products,然后将第ProductId
插入Config表中的第二个配置。
我拔掉头发试图覆盖并阅读this和this之类的链接,但仍然无法让它按照我的意愿去做。我正在使用现有数据和代码,所以我宁愿不更改数据库表定义或域对象。如果我们可以避免讨论领域模型设计那么好,那么还有比这个例子更多的内容。我有一个链接到这个项目的峰值here(假设数据库存在)
我目前的流利映射是:
public class ProductOverrides : IAutoMappingOverride<Product>
{
public void Override(AutoMapping<Product> mapping)
{
mapping.Id(x => x.Id).Column("ProductId");
mapping.Table("Products");
}
}
public class ConfigOverrides : IAutoMappingOverride<Config>
{
public void Override(AutoMapping<Config> mapping)
{
mapping.Id(x => x.ConfigId);
}
}
答案 0 :(得分:4)
您正尝试将一对一关系映射为一对多关系,方法是将多方面两次映射。那不行。 NHibernate在一对一的定义上是严格的,并要求双方都有相同的主键,因此也不会有效。
我butted heads with this before,我发现最好的解决方法是将其建模为标准的多对多,但只允许通过封装对它的访问来允许集合中的一个项目。在你的情况下,我猜测产品将是一方并且配置许多。
答案 1 :(得分:2)
我不确定Config是否在别处使用,但您可以忽略ConfigId作为其身份
public class Config
{
public int Id { get; set; }
public Product Product { get; set; }
public string ConfigField1 { get; set; }
public string ConfigField2 { get; set; }
}
public class ProductMap : ClassMap<Product>
{
public class ProductMap()
{
HasOne(p => p.Config);
}
}
public class ConfigMap : ClassMap<Config>
{
public class ConfigMap()
{
Id(c => c.Id, "ProductId").GeneratedBy.Foreign("Product");
References(c => c.Product, "ProductId");
Map(c => ...);
}
}
答案 2 :(得分:1)
另一个想法是加入并映射为Component
public class ProductMap : ClassMap<Product>
{
public class ProductMap()
{
Join("Config", join =>
{
join.KeyColumn("ProductId");
join.Component(p => p.Config, c =>
{
c.Map(...);
});
}
}
}
缺点是您无法直接查询Config,您必须通过Product
进行查询