我有以下两个实体:
public class Artist
{
[Key]
public string ArtistId { get; set; }
public string Name { get; set; }
public virtual ICollection<Genre> Genres { get; set; }
}
public class Genre
{
[Key]
public int GenreId { get; set; }
public string Name { get; set; }
public virtual ICollection<Artist> Artist { get; set; }
}
在我的程序中,我创建了一些艺术家并希望将它们保存:
using (var context = new ArtistContext())
{
var artists = _fullArtists.Select(x => x.Artist);
foreach (var artist in artists)
{
context.Artists.AddOrUpdate(artist);
}
context.SaveChanges();
}
Entity Framework正确地创建了三个表:
艺术家(ArtistId,Name)
流派(GenreId,Name)
艺术家流派(ArtistId,GenreId)
但不幸的是,当我的艺术家样本数据看起来像这样时:
var a1 = new Artist { Name = "a1" };
a1.Genres.Add(new Genre { Name="rock"});
var a2 = new Artist { Name = "a2" };
a2.Genres.Add(new Genre { Name="rock"});
这将在表Genre
中创建2条记录:
IdName
1 rock
2 rock
而不是创建一次并重复使用。
- 您知道这是否是配置问题,或者如何告诉EF不要插入重复项,而是重复使用现有项吗?
提前感谢
编辑:不幸的是,Sergey Berezovskiy的解决方案没有起作用(或者可能是我做错了:D)
现在我拥有以下内容:
using (var workUnit = WorkUnitFactory.CreateWorkUnit())
{
var snapShot = new Snapshot { Date = DateTime.Now.Date };
//ICollection<Genre> genres = _fullArtists.Select(x => x.ToArtist(snapShot)).SelectMany(x => x.Genres).Distinct(new GenreComparer()).ToList();
//workUnit.Repository<IGenreRepository>().InsertEntities(genres);
//workUnit.Commit();
var artists = _fullArtists.Select(x => x.ToArtist(snapShot)).ToList();
workUnit.Repository<IArtistRepository>().InsertEntities(artists);
workUnit.Commit();
}
ArtistExtensions.cs
public static class ArtistExtensions
{
public static Artist ToArtist(this FullArtistWrapper value, Snapshot snapShot)
{
if (value == null) { throw new ArgumentNullException(); }
var artist = new Artist
{
ArtistId = value.Id,
Name = value.Name
};
var genres = value.Genres.Select(x => x.ToGenre()).ToList();
artist.Genres.AddRange(genres);
return artist;
}
}
GenreExtensions.cs
public static class GenreExtensions
{
public static Genre ToGenre(this string value)
{
using (var workUnit = WorkUnitFactory.CreateWorkUnit())
{
return workUnit.Repository<IGenreRepository>().GetGenres().FirstOrDefault(x => x.Name == value) ??
new Genre {Name = value};
}
}
}
很遗憾,EF在数据库中仍会插入重复的
Genres
。InsertEntities(...)
是这样的:public void InsertEntities<TPersistentEntity>(ICollection<TPersistentEntity> persistentEntitiesToBeInserted) where TPersistentEntity : PersistenceEntity
{
persistentEntitiesToBeInserted.ForEach(this.Add);
}
public void Add(PersistenceEntity entity)
{
var dbSet = this.Context.Set(entity.GetType());
dbSet.Add(entity);
}
- 我是否误解了Sergey的答案,或者EF仍然插入重复数据的另一个原因是什么?
再次感谢