简体   繁体   中英

both one-to-one and one-to-many relations of same type in ef core

My next question is regarding Entity Framework Core 2 (db - sql server) and having entities with both one-to-one and one-to-many of the same type.

I have these 2 entities:

Topic:

public class Topic
{
    [Key]
    public int TopicID { get; set; }
    public int MessageID { get; set; }
    [ForeignKey("MessageID")]
    public Message Message { get; set; }
    public IEnumerable<Message> Messages { get; set; }
}

Message:

public class Message
{
    [Key]
    public int MessageID { get; set; }
    public int TopicID { get; set; }
    public Topic Topic { get; set; }
    public string Content { get; set; }
}

And I set them up in my context like this:

builder.Entity<Topic>().HasKey(t => new { t.TopicID });
builder.Entity<Topic>()
    .HasOne(t => t.Message);
builder.Entity<Topic>()
    .HasMany(t => t.Messages)
    .WithOne(m => m.Topic);
builder.Entity<Message>().HasKey(m => new { m.MessageID });
builder.Entity<Message>()
    .HasOne(m => m.Topic)
    .WithMany(t => t.Messages);

So I have have both one-to-one and one-to-many relations of the same entity type:

  • the topic has 1 main message and a list of messages (which are the replies).

When I try to create a new topic like this:

Message newMessage = new Message()
{
    Content = content
};
Topic newTopic = new Topic()
{
    Message = newMessage,
};

context.Topics.Add(newTopic);
context.SaveChanges();
  • the topic gets created with a valid topicId
  • the message gets created with a valid messageId
  • the topic gets the new messageId
  • but the message does not get the new topicId, instead it is set to 0

So the next thing I tried to to was create the new topic & message like this:

Message newMessage = new Message()
{
    Content = content
};
Topic newTopic = new Topic()
{
    Message = newMessage,
    Messages = new List<Message>() { newMessage }
};

context.Topics.Add(newTopic);
context.SaveChanges();

But then I received the following exception:

fail: Microsoft.EntityFrameworkCore.Update[10000] An exception occurred in the database while saving changes for context type 'MyContext'. System.InvalidOperationException: Unable to save changes because a circular dependency was detected in the data to be saved: 'ForeignKey: Message {'TopicID'} -> Topic {'TopicID'} ToDependent: Messages ToPrincipal: Topic, ForeignKey: Topic {'MessageID'} -> Message {'MessageID'} ToPrincipal: Message'. at Microsoft.EntityFrameworkCore.Internal.Multigraph'2.BatchingTopologicalSort(Func'2 formatCycle) at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.TopologicalSort(IEnumerable'1 commands) at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.d__8.MoveNext() at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(Tuple'2 parameters) at Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func'3 operation, Func'3 verifySucceeded) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable'1 commandBatches, IRelationalConnection connection) at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IReadOnlyList'1 entries) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList'1 entriesToSave) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSucc ess) at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)

What am I doing wrong?

How can I create in one connection to the db the topic and message with each-other's right foreign keys?

您必须将Topic.MainMessage设置为可选,并在您对Save.Changes()设置Topic.Messages之后进行设置。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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