Reputation: 11221
I'm trying to seed data in many-to-many relation in my database, but I cannot make a migration. I'm using Entity Framework Core 5.0.6.
Here are my models:
The general idea is: one Tag can belong to many Topics. One Topic can have many Tags.
Tag.cs:
public class Tag
{
public int Id { get; set; }
// [...]
public ICollection<Topic> Topics { get; set; }
public List<TopicTag> TopicTags { get; set; }
}
Topic.cs
public class Topic
{
public int Id { get; set; }
// [...]
public ICollection<Tag> Tags { get; set; }
public List<TopicTag> TopicTags { get; set; }
}
And TopicTag.cs
public class TopicTag
{
public int TopicId { get; set; }
public Topic Topic { get; set; }
public int TagId { get; set; }
public Tag Tag { get; set; }
}
Here is what I have in OnModelCreating
in my ApplicationDbContext
:
// [...]
// Configuring relation
modelBuilder.Entity<Topic>()
.HasMany(topic => topic.Tags)
.WithMany(x => x.Topics)
.UsingEntity<TopicTag>(
j => j
.HasOne(tt => tt.Tag)
.WithMany(t => t.TopicTags)
.HasForeignKey(t => t.TagId),
j => j
.HasOne(tt => tt.Topic)
.WithMany(t => t.TopicTags)
.HasForeignKey(t => t.TopicId),
j => { j.HasKey(t => new {t.TopicId, t.TagId}); }
);
modelBuilder.Entity<Tag>()
.HasMany(tag => tag.Topics)
.WithMany(x => x.Tags)
.UsingEntity<TopicTag>(
j => j
.HasOne(tt => tt.Topic)
.WithMany(t => t.TopicTags)
.HasForeignKey(t => t.TopicId),
j => j
.HasOne(tt => tt.Tag)
.WithMany(t => t.TopicTags)
.HasForeignKey(t => t.TagId),
j => { j.HasKey(t => new {t.TopicId, t.TagId}); }
);
// [...]
// Seeding data
for (int t = -1; t >= -4; t--)
{
builder.Entity<Tag>().HasData(new Tag()
{
Id = t,
Name = "tag" + t
});
}
for (int y = -1; y >= -10; y--)
{
builder.Entity<Topic>().HasData(new Topic()
{
Id = y,
// [...]
});
}
// Finally joining them together
for (int y = -1; y >= -10; y--)
{
builder.Entity<TopicTag>().HasData(new TopicTag()
{
TopicId = y,
TagId = -1 * ((y % 4) + 1)
});
}
As a result, when I try to create new migration, I receive this error:
The value of 'TopicTag.TagId' is unknown when attempting to save changes. This is because the property is also part of a foreign key for which the principal entity in the relationship is not known.
To be honest, I don't understand the meaning of an error message. TopicTag.TagId
is known, because I'm specifying it while creating new TopicTag
in for loop. Moreover, all ids I'm referencing there are created before.
Upvotes: 1
Views: 119
Reputation: 56745
I fear that you've fallen afoul of a nasty "feature" of C#'s modulo operator.
Let's consider your last loop:
/ Finally joining them together
for (int y = -1; y >= -10; y--)
{
builder.Entity<TopicTag>().HasData(new TopicTag()
{
TopicId = y,
TagId = -1 * ((y % 4) + 1)
});
}
So what happens on the first iteration through the loop? You may think that (-1 % 4)
returns something reasonable like 3, but in fact it actually returns -1! So the whole expression resolves to -1 * (-1 + 1) == 0
and not -4 which is probably what you wanted. And since you don't have any tag IDs that are zero, that's where the TagId is not known
message is coming from.
To address this you can try some of the solutions here: Mod of negative number is melting my brain
Upvotes: 1