Entity Framework 6插入重复值

问题描述 投票:7回答:3

我有以下两个实体:

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();
}

实体框架正确创建了三个表:

Artist(ArtistId,Name)流派(GenreId,名称)ArtistGenre(ArtistId,Gen​​reId)

但是不幸的是,当我的艺术家样本数据如下:

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条记录:

Id 名称1 石头2 岩石

而不是一次创建然后再使用它。

  • 您知道这是否是配置问题,还是如何告诉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);
    }
  • 我是否误解了谢尔盖的答案,或者EF仍然插入重复项的另一个原因是什么?

再次感谢

c# .net entity-framework ef-code-first entity-framework-6
3个回答
5
投票

从EF的角度来看,如果两个实体指向数据库中的同一行,则它们是相同的。即两个实体应具有相同的非零密钥。


1
投票

在您将Artist链接到流派的类中,然后在代码中使用Name字段添加了2 Genre。


1
投票

我认为有两个可能的原因不起作用:

© www.soinside.com 2019 - 2024. All rights reserved.