简体   繁体   English

具有多个不同类型的多个父项之一的实体

[英]Entity having one of multiple parents, which are different types

I'm currently working on a C# EF MVC project in combination with a MySql database and I am trying to setup my database schema through a code-first approach (with migrations enabled). 我目前正在与MySql数据库结合使用C#EF MVC项目,并且正在尝试通过代码优先方法(启用迁移)来设置数据库架构。 For my example I have simplified my model down to the 3 classes shown below: 对于我的示例,我将模型简化为以下所示的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
  // ...
}

To make sure the relations were mapped properly I also used the EF Fluent Api on my DbContext. 为了确保正确映射关系,我还在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();
  }
}

The issue I have is when I try to add a Message with MessageContent to my database I get: 我遇到的问题是,当我尝试将包含MessageContentMessage添加到数据库时,我得到:

Cannot add or update child row: a foreign key constraint fails ("DbName"."MessageContent", CONSTRAINS "FK_MessageContent_CorrectedContent_MessageContentId " FOREIGN KEY ("MessageContentId ") REFERENCES "CorrectedContent" ("CorrectedContentId") ON DELETE CASCADE ON UPDATE CASCADE) 无法添加或更新子行:外键约束失败(“ DbName”。“ MessageContent”,约束“ FK_MessageContent_CorrectedContent_MessageContentId” FOREIGN KEY(“ MessageContentId”)参考“ CorrectedContent”(“ CorrectedContentId”)在更新级联时删除级联)

I have tried putting both entities on "withOptional" but that didn't work, I also tried working with a mutual interface for both the Message and CorrectedContent . 我尝试将两个实体都放在“ withOptional”上,但是那没有用,我还尝试了使用MessageCorrectedContent的共同接口。

So the Message should have a one-to-one-or-zero relationship to MessageContent , CorrectedContent also has a one-to-one-or-zero relationship with MessageContent and Message has a one-to-one-or-zero with CorrectedContent . 所以Message应该有一个一到一或零关系MessageContentCorrectedContent也有一到一或零以关系MessageContentMessage有一到一或零与CorrectedContent

My current solution: 我当前的解决方案:

Because the XSD (and send in xml files) where my data would come from was too complicated to transform into a proper database model I opted for a less than ideal solution where I only have 2 classes like shown below. 因为我的数据所来自的XSD(并发送xml文件)太复杂而无法转换为合适的数据库模型,所以我选择了一个不太理想的解决方案,其中只有两个类,如下所示。

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 ...
}

In the model I only open the first element of a received XML which is always of type Message . 在模型中,我只打开始终为Message类型的接收到的XML的第一个元素。 Then I look for the child element and get its type which is MessageType . 然后,我寻找子元素并获取其类型为MessageType The XMLString property contains this child in string representation. XMLString属性以string表示形式包含此子级。

I know this is a bad designed solution but it works for my application just fine. 我知道这是一个糟糕的设计解决方案,但它对我的应用程序正常工作。 I use the XSD (classes) that was provided to my on my front-end so I only have to parse the XMLString to the XSD classes. 我使用前端提供给我的XSD(类),因此我只需要将XMLString解析为XSD类。

Any better solutions are always welcome. 始终欢迎任何更好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM