.net - 一对一的可选关系,两端可选且两个 FK

标签 .net entity-framework ef-code-first entity-framework-6

我正在关注这个问题:EF Code First - 1-to-1 Optional Relationship

我的关系设置如下:

public class Review {
    [Key]
    public int ReviewId { get; set; }

    public virtual Payment Payment { get; set; }
}

public class Payment {
    [Key]
    public int PaymentId { get; set; }

    [ForeignKey("Review")]
    public int? ReviewId { get; set; }
    public virtual Review Review { get; set; }
}

    public class ReviewConfiguration : EntityTypeConfiguration<Review>
{
    public ReviewConfiguration()
    {
        // One-to-One Optional
        HasOptional<Payment>(s => s.Payment).WithOptionalDependent(s => s.Review).Map(s => s.MapKey("PaymentId"));
    }
}

我得到其中一个键有效,但另一个键从未映射为可选 FK:

enter image description here

我做错了什么?

我见过一些涉及创建空列表等的奇怪的 hacky 解决方案 - 不是我要找的。我在这里寻找合适的方法 - 它必须存在...对吗?

更新

我现在正在使用上面的内容 - 当我手头有付款并需要访问或删除评论时,我必须对 [伪 FK] ReviewId 进行另一次查找,这非常糟糕。

最佳答案

在任何一对一关联中,EF 只使用一个外键。当需要关联时,外键也将是依赖实体的主键,解释为here .

当关联是可选的时,两个实体应该能够独立存在。所以他们的主键不能是外键,因为 PKs 不能是可选的。这里需要一个额外的可为空的 FK 字段来建立可选关联。

在您的情况下,技术上哪个实体具有 FK 字段并不重要(逻辑上,它可能)。我用过这个模型:

public class Review
{
    [Key]
    public int ReviewId { get; set; }
    public virtual Payment Payment { get; set; }
}

public class Payment
{
    [Key]
    public int PaymentId { get; set; }

    public Review Review { get; set; }
}

有了这个映射:

public class ReviewConfiguration : EntityTypeConfiguration<Review>
{
    public ReviewConfiguration()
    {
        // One-to-One Optional
        HasOptional(s => s.Payment)
            .WithOptionalDependent(s => s.Review)
            .Map(s => s.MapKey("PaymentId"));
    }
}

(因此,除了 Payment.ReviewId 之外,这与您问题中的模型 + 映射相同)。

现在我可以做...

db.Set<Review>().Add(new Review { Payment = new Payment() });
db.Set<Payment>().Add(new Payment { Review = new Review() });
db.SaveChanges();

... db 当然是上下文。现在两个表的内容是:

PaymentId
-----------
1
2

ReviewId    PaymentId
----------- -----------
1           1
2           2

我可以像这样双向查询数据:

var data = db.Set<Review>().Include(r => r.Payment).ToList();

var data = db.Set<Payment>().Include(r => r.Review).ToList();

但是除了ReviewConfiguration,我还可以使用...

public class PaymentConfiguration : EntityTypeConfiguration<Payment>
{
    public PaymentConfiguration()
    {
        // One-to-One Optional
        HasOptional(s => s.Review)
            .WithOptionalDependent(s => s.Payment)
            .Map(s => s.MapKey("ReviewId"));
    }
}

现在 Payment 表中将有一个 FK 字段 ReviewId,其余代码无需更改即可工作。

关于.net - 一对一的可选关系,两端可选且两个 FK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37040666/

相关文章:

Java/.NET 生成具有 cookie 设置的浏览器

ios - ld : framework not found -framework ERROR

c# - codefirst 数据库未创建

c# - 如何知道项目是代码优先还是数据库优先?

entity-framework - 应用程序配置文件中的连接字符串 'MyConnection' 不包含所需的providerName属性。”

entity-framework - 在每个单元测试之前重新创建和重新设置 LocalDb

c# - SOAP header 身份验证不起作用?

C#调用另一个Form的方法

.net - 在平面上画线的算法

.net - 使用 .Net Entity Framework 和 Devart dotConnect for MySQL 的时间戳问题