【问题标题】:EF6 One to One or Zero Relationship (Fluent API)EF6 一对一或零关系(Fluent API)
【发布时间】:2015-11-15 21:45:21
【问题描述】:

我有这样的类(简化):

public class Transaction
{
    public int LocalId { get; set; }
    public int MachineId { get; set; }
    public virtual Machine Machine { get; set; }       
    public int? MoneyId { get; set; }
    public virtual TransactionMoney Money { get; set; }
}

public class Machine
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class TransactionMoney
{
    public int LocalId { get; set; }
    public int MachineId { get; set; }
    public virtual Machine Machine { get; set; }
    public int TransactionId { get; set; }
    public virtual Transaction Transaction { get; set; }
}

我想建立关系 Transaction 1 0...1 TransactionMoney,其中 Money 中的外键应该是 TransactionId 和 MachineId(连接到交易的 LocalId 和 MachineId)。我需要在 fluent API 中执行此操作。

我试过的是:

    modelBuilder.Entity<Transaction>()
                .HasOptional(t => t.Money)
                .WithRequired(t => t.Transaction)
                .HasForeignKey() <--- there is no such method

在另一边

modelBuilder.Entity<TransactionMoney>()
    .HasRequired(t => t.Transaction)
    .WithOptional(t => t.Money)
            .HasForeignKey() <--- there is no such method

【问题讨论】:

  • Transaction的主键是什么?
  • 配对 LocalId 和 MachineId
  • 好吧,那么TransactionMoney 也应该有一个主键LocalId, MachineId,它也是Transaction 的FK。这就是在 EF 中实现 1:1 的方式。
  • 就像@GertArnold 所说,您的模型完全不正确。

标签: c# entity-framework ef-fluent-api


【解决方案1】:

你可以用这样的东西

modelBuilder.Entity<TransactionMoney>()
    .HasRequired(t => t.Transaction)
    .WithOptional(t => t.Money)
    .Map(a => a.MapKey("TransactionId", "MachineId"));


事实证明,您所针对的设计无法在 EF 中完成。我能够得到的最接近如下。但在我去之前,有一些事情需要注意。 MoneyId 字段已从 Transaction 中删除。 LocalId 字段已从 TransactionMoney 中删除。外键是用数据注释指定的。如果其中任何一个不可接受,请跳过其余部分。

实体:

public class Transaction
{
    public int LocalId { get; set; }
    public int MachineId { get; set; }
    public virtual Machine Machine { get; set; }
    public virtual TransactionMoney Money { get; set; }
}

public class Machine
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Transaction> Transactions { get; set; }
    public virtual ICollection<TransactionMoney> Money { get; set; }
}

public class TransactionMoney
{
    public int MachineId { get; set; }
    public virtual Machine Machine { get; set; }
    public int TransactionId { get; set; }
    [ForeignKey("TransactionId,MachineId")]
    public virtual Transaction Transaction { get; set; }
}

配置

modelBuilder.Entity<Transaction>()
    .HasKey(t => new { t.LocalId, t.MachineId })
    .HasRequired(t => t.Machine)
    .WithMany(t => t.Transactions)
    .HasForeignKey(t => t.MachineId);

modelBuilder.Entity<TransactionMoney>()
    .HasRequired(t => t.Machine)
    .WithMany(t => t.Money)
    .HasForeignKey(t => t.MachineId);

modelBuilder.Entity<TransactionMoney>()
    .HasKey(t => new { t.TransactionId, t.MachineId })
    .HasRequired(t => t.Transaction)
    .WithOptional(t => t.Money);

【讨论】:

  • 我知道,但我想使用外键关联,而不是独立关联
  • 我读到独立关联是在实体框架中实现一对一关系所需要的,所以我使用了你的方式并且它有效,但是在 TransactionMoney 我也引用了 Machine 并且它创建了另一个名为Machine_Id。如何使其使用 fluent API 中定义的“MachineId”字段?
  • @Lukas 对不起,伙计,看起来不可能。
猜你喜欢
  • 1970-01-01
  • 2014-05-07
  • 1970-01-01
  • 2019-01-04
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-01
相关资源
最近更新 更多