我正在尝试使用NHibernate Fluent映射来模拟我的业务逻辑。
我有一个像这样的实体模型:
public class Request
{
...
public virtual Response Response {get; set;}
}
public class Response
{
...
public virtual Request Request {get; set;}
}
我的Request
实体应该能够在没有Response
实体的情况下存在,反之亦然我的Response
实体应该能够在没有Request
的情况下存在。这可以映射为一对一映射吗?我知道Response
可以在没有Request
的情况下存在,但这可能发生在我的情况下。
我已阅读文章I Think You Mean a Many-to-one, Sir,但我仍然认为多对一映射对我来说不对,因为我的实体都没有列表响应或请求。
如何映射这种情况?
编辑1
使用来自How to do a fluent nhibernate one to one mapping?的外键关联的我的Fluent地图:
public RequestMap()
{
Id(x => x.Id).GeneratedBy.Guid();
References(x => x.Response, "ResponseId").Unique().Cascade.All();
}
public ResponseMap()
{
Id(x => x.Id).GeneratedBy.Guid();
HasOne(x => x.Request).Cascade.All().PropertyRef(x => x.Response);
}
这似乎在许多情况下都有效,但是当我尝试添加多个Request
实体而没有引用Response
实体时,我收到此错误:
System.Data.SqlClient.SqlException:违反UNIQUE KEY 约束'UQ__Request__346FA94719588CEC'。无法插入重复 对象'dbo.Request'中的键。重复的键值是 ()。声明已经终止。
编辑2
public RequestMap()
{
Id(x => x.Id).GeneratedBy.Guid();
HasOne(x => x.Response).Cascade.All().PropertyRef(x => x.Request);
}
public ResponseMap()
{
Id(x => x.Id).GeneratedBy.Guid();
References(x => x.Request, "RequestId").Cascade.All();
}
使用此映射时,执行request.Response = response;
时不会保留对象之间的映射。我应该保护 setter 吗?
答案 0 :(得分:1)
我可能误解了这个问题,但这似乎要求您使用“引用”映射其中一个实体,而另一个实体使用“> Inversed< References”映射。
答案 1 :(得分:1)
您的编辑1的问题来自以下事实:
Request
表对“ResponseId”列有唯一约束。即每行必须具有不同的值Requests
确实有NULL
而不是任何值...所有这些值。这打破了上述要求,让每一行都是唯一的在这种情况下,解决方案是从ResponseId
列中删除数据库级别上的唯一键。因为这是我们需要的(请求没有响应)。即应该允许在ReponseId中使用很少的并发NULL值。
但有点令我困惑的是命名:Reponse / Request
在我看来,Request (来自我的网站开发经验)是触发器,第一个触发器。如果一切正常,则会发回一个响应。你的映射不应该被反转吗? Response表包含RequestId?
我在问题中看到了这句话:
我的请求实体应该能够在没有响应实体的情况下存在,反之亦然我的响应实体应该能够在没有请求的情况下存在
好吧,那么......让我们假设:Response
可以不在没有Request
的情况下生活...然后您的映射(但是反转)应该可以正常工作唯一键约束。
更重要的是,纯one-to-one
映射将起作用,因为这两个映射可以共享主键(由Request生成,由Response使用)