首页 > 解决方案 > 具有多个父级之一的实体,它们是不同的类型

问题描述

我目前正在结合 MySql 数据库开发 C# EF MVC 项目,并且我正在尝试通过代码优先方法(启用迁移)设置我的数据库模式。对于我的示例,我已将模型简化为如下所示的 3 个类:

public class Message
{
  [Key]
  public int MessageId { get; set; }
  // Some properties ...

  // There will always be one filled in and not the other
  public virtual CorrectedContent CorrectedContent { get; set; }
  public virtual MessageContent MessageContent { get; set; }
}

public class CorrectedContent
{
  [Key]
  public int CorrectedContentId { get; set; }

  public virtual Message Message { get; set; }
  // ...
  public MessageContent MessageContent { get; set; }  // Nullable
}

public class MessageContent
{
  [Key]
  public int MessageContentId { get; set; }

  public virtual Message Message { get; set; }
  public virtual CorrectedContent CorrectedContent
  // ...
}

为了确保正确映射关系,我还在 DbContext 上使用了 EF Fluent Api。

public class TestContext: DbContext
{
  public TestContext(): base("TestContext") { }
  // My DbSets and such ...

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

    modelBuilder.Entity<CorrectedContent>()
      .HasOptional(x => x.MessageContent)
      .WithRequired(y => y.CorrectedContent)
      .WillCascadeOnDelete();

    modelBuilder.Entity<Message>()
      .HasOptional(x => x.MessageContent)
      .WithRequired(y => y.Message)
      .WillCascadeOnDelete();

    modelBuilder.Entity<Message>()
      .HasOptional(x => x.CorrectedContent)
      .WithRequired(y => y.Message)
      .WillCascadeOnDelete();
  }
}

我遇到的问题是,当我尝试将Messagewith添加MessageContent到我的数据库时,我得到:

无法添加或更新子行:外键约束失败(“DbName”。“MessageContent”,CONSTRAINS“FK_MessageContent_CorrectedContent_MessageContentId”外键(“MessageContentId”)参考“CorrectedContent”(“CorrectedContentId”)ON DELETE CASCADE ON UPDATE CASCADE)

我已经尝试将两个实体都放在“withOptional”上,但这没有用,我还尝试为Messageand使用相互接口CorrectedContent

因此Message应该与 具有一对一或零关系MessageContentCorrectedContent也与 具有一对一或零关系,MessageContent并且与Message具有一对一或零关系CorrectedContent

标签: c#entity-framework

解决方案


我目前的解决方案:

因为我的数据来自的 XSD(并发送 xml 文件)太复杂而无法转换为适当的数据库模型,所以我选择了一个不太理想的解决方案,我只有 2 个类,如下所示。

public class Message
{
  [Key]
  public int MessageId { get; set; }
  // Some properties ...

  public virtual MessageContent MessageContent { get; set; }
}

public class MessageContent
{
  [Key]
  public int MessageContentId { get; set; }

  public virtual Message Message { get; set; }

  [Required, Column(TypeName = "text")]
  public string XMLString { get; set; }

  [Required]
  public MessageType Type { get; set; }
}

public enum MessageType
{
  Correction,
  Normal,
  // more options ...
}

在模型中,我只打开接收到的 XML 的第一个元素,该元素始终为Message. 然后我查找子元素并获取其类型为MessageType. 该XMLString属性在string表示中包含此子项。

我知道这是一个糟糕的设计解决方案,但它适用于我的应用程序就好了。我使用在前端提供给我的 XSD(类),因此我只需将 XMLString 解析为 XSD 类。

任何更好的解决方案总是受欢迎的。


推荐阅读