Если вы сказали, что есть отношение Many-To-Many
, которое PostTag
является таблицей соединений между Tag
и Post
, то ваши модели не показывают никакого отношения many-to-many
, поэтому из того, что я видел, есть one-to-many
между Post
и Tag
из-за определения вашей модели.
если вы хотите установить many-to-many
связь между ними, вы должны что-то вроде ниже:
public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Post> Posts { get; set; }
public Tag()
{
Posts = new HashSet<Post>();
}
}
public class Post
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
public Post()
{
Tags = new HashSet<Tag>();
}
}
ив OnModelCreating
создайте связь по API, как показано ниже:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Tag>()
.HasMany(s => s.Posts)
.WithMany(c => c.Tags)
.Map(cs =>
{
cs.MapLeftKey("TagId");//TagId
cs.MapRightKey("PostId");//PostId
cs.ToTable("PostTag");
});
}
или наоборот
modelBuilder.Entity<Post>()
.HasMany(s => s.Tags)
.WithMany(c => c.Posts)
.Map(cs =>
{
cs.MapLeftKey("PostId");//PostId
cs.MapRightKey("TagId");//TagId
cs.ToTable("PostTag");
});
, как вы можете видеть и знать, что в базе данных должна быть таблица с именем PostTag
которые имеют два столбца в качестве ключей и имеют скрипт типа:
CREATE TABLE [dbo].[PostTag](
[TagId] [int] NOT NULL,
[PostId] [int] NOT NULL,
CONSTRAINT [PK_PostTag] PRIMARY KEY CLUSTERED
(
[TagId] ASC,
[PostId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[PostTag] WITH CHECK ADD CONSTRAINT [FK_PostTag_Post] FOREIGN KEY([PostId])
REFERENCES [dbo].[Post] ([Id])
GO
ALTER TABLE [dbo].[PostTag] CHECK CONSTRAINT [FK_PostTag_Post]
GO
ALTER TABLE [dbo].[PostTag] WITH CHECK ADD CONSTRAINT [FK_PostTag_Tag] FOREIGN KEY([TagId])
REFERENCES [dbo].[Tag] ([TagId])
GO
ALTER TABLE [dbo].[PostTag] CHECK CONSTRAINT [FK_PostTag_Tag]
GO
. Для получения дополнительной информации посмотрите здесь .
ОБНОВЛЕНИЕ:
если вы хотите установить zero-to-many
отношение между Post
и Tag
, то модели должны быть такими, как показано ниже:
public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
public int? PostId { get; set; }
}
public class Post
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
public Post()
{
Tags = new HashSet<Tag>();
}
}
и отношение один-ко-многим с текущими API:
modelBuilder.Entity<Post>()
.HasMany(o1 => o1.Tags);
в качестве комментария вы не хотите, чтобы у Tag
было свойство навигации, поэтому вы должны определить свойство как Nullable
в Tag
это симметричный ключ, если между ними есть связь, вы должны установить связь хотя бы с помощью свойства navte или свойства Nullable
.
Правильный ответ пришел от здесь (без изменений): если вы хотите присвоить тег существующему сообщению, вы должны сначала найти это сообщение, а затем добавить к нему тег, если этот тег существует в БД, между тегом и найденным сообщением будет установлена связь, если этот тег делаетне существует, тег будет вставлен в БД,
Посмотрите на это:
var post = context.Posts.SingleOrDefault(x => x.Id == 4);//That Id would be you specific Post Id
var existTag = context.Tags.SingleOrDefault(x => x.Id == 1); //Exist Tag in DB
post.Tags.Add(existTag);
context.SaveChanges();
//Inserting new tag to DB and assign it to Post also
Tag newTag = new Tag // Does not exist in DataBase
{
Name = "tag2"
};
post.Tags.Add(newTag);// By this tag2 will be insert into Tag table first and then added to post (insert new record to PostTag)
context.SaveChanges();