为什么要尝试插入多个?

发布于 2024-12-11 16:09:52 字数 1342 浏览 0 评论 0原文

我有以下方法

public static Artist ProcessArtist(Artist artist, Entities db) {
    var artistLookup = db.Artist.SingleOrDefault(x => x.ExternalId == artist.ExternalId);
    if (artistLookup == null) {
        artistLookup = new Artist {
            ExternalId = artist.ExternalId,
            Name = artist.Name
        };
        db.Artist.AddObject(artistLookup);
        db.SaveChanges();
    }
    return artistLookup;
}

我使用它的方式是传入一个仅设置了 ExternalIdNameArtist 对象,但是它根本没有连接到我的实体上下文。它是从外部来源获取的。

当我调用db.SaveChanges()时,它会抛出异常,说我已经打破了ExternalId的唯一键约束。我无法弄清楚它将如何尝试插入多个。

有人有任何见解吗?谢谢!

编辑:我在下面添加了调用代码

var albums = from item in externalSource
             select new Album {
                 Country = country // Another entity, one that exists in the database
                 Name = item["Name"].Value,
                 Artist = new Artist {
                     ExternalId = Int32.Parse(item["ArtistId"].Value),
                     Name = item["ArtistName"].Value
                 }
             };

,然后为每个专辑调用 ProcessArtist

foreach (var album in albums) {
    album.Artist = ProcessArtist(album.Artist, db);
    db.Album.AddObject(album);
}

I have the following method

public static Artist ProcessArtist(Artist artist, Entities db) {
    var artistLookup = db.Artist.SingleOrDefault(x => x.ExternalId == artist.ExternalId);
    if (artistLookup == null) {
        artistLookup = new Artist {
            ExternalId = artist.ExternalId,
            Name = artist.Name
        };
        db.Artist.AddObject(artistLookup);
        db.SaveChanges();
    }
    return artistLookup;
}

The way I'm using it is that I pass in an Artist object that just has ExternalId and Name set, but it's not connected to my entity context at all. It was grabbed from an external source.

When I call db.SaveChanges() it throws, saying I've broken my unique key constraint for ExternalId. I can't figure out how it would be trying to insert multiples.

Does anyone have any insight? Thanks!

EDIT: I've added my calling code below

var albums = from item in externalSource
             select new Album {
                 Country = country // Another entity, one that exists in the database
                 Name = item["Name"].Value,
                 Artist = new Artist {
                     ExternalId = Int32.Parse(item["ArtistId"].Value),
                     Name = item["ArtistName"].Value
                 }
             };

then I call ProcessArtist for each album

foreach (var album in albums) {
    album.Artist = ProcessArtist(album.Artist, db);
    db.Album.AddObject(album);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空城缀染半城烟沙 2024-12-18 16:09:52
var artistLookup = db.Artist.SingleOrDefault(x => x.ExternalId == artist.ExternalId);
//in this line  you get an artist from the database


//i dont know why would you want to insert the artist that you just get from the database
//you are reinserting an existing record. That's the reason you get the error
    db.Artist.AddObject(artistLookup);
    db.SaveChanges();
var artistLookup = db.Artist.SingleOrDefault(x => x.ExternalId == artist.ExternalId);
//in this line  you get an artist from the database


//i dont know why would you want to insert the artist that you just get from the database
//you are reinserting an existing record. That's the reason you get the error
    db.Artist.AddObject(artistLookup);
    db.SaveChanges();
山人契 2024-12-18 16:09:52

看看你的 for 循环,我不认为错误是因为 Artist 实体,但它可能是一个不同的实体,因为在 for 循环中的每个步骤中,你在添加 Artist 后保存上下文,但你有待添加的专辑,并且它专辑可能存在关键违规,但仍待处理。

好的,我明白了,当您分配艺术家时,您仍然有其他没有 ID 的专辑,当您添加或附加任何内容到对象上下文时,整个对象图都会被附加。现在的问题是,您正在重用之前创建的对象。

在您的代码中,从 rss 创建对象时,不要使用实体,而是使用一些代理类。例如 RAlbum 和 RArtist 并在 for 循环中更改它。

var albums = 来自 externalSource 中的项目;
 选择新的 RAlbum {
Country = Country // 另一个实体,存在于数据库中
             名称=项目[“名称”].值,
       艺术家 = 新 RArtist {
                    ExternalId = Int32.Parse(item["ArtistId"].Value),
                   名称 = item["ArtistName"].Value
                 }
             };

public static Artist ProcessArtist(RArtist artist, Entities db) {
    var artistLookup = db.Artist.SingleOrDefault(x => x.ExternalId == artist.ExternalId);
    if (artistLookup == null) {
        artistLookup = new Artist {
            ExternalId = artist.ExternalId,
            Name = artist.Name
        };
        db.Artist.AddObject(artistLookup);
        db.SaveChanges();
    }
    return artistLookup;
}


foreach (var album in albums) {
    Album a = new Album();
    // copy properties of a from album
    a.Artist = ProcessArtist(album.Artist, db);
    db.Album.AddObject(a);
}

Looking at your for loop, I don't think the error is because of Artist entity, but it may be a different entity as in every step in for loop, you are saving context after adding the Artist but you have pending added albums and it may be having key violation for album that was still pending.

Ok I got it, When you are assigning artist, you still have other albums that exist without Ids and when you add or attach anything to object context, entire object graph gets attached. Now here the problem is, you are reusing objects created before.

In your code, where you are creating objects from rss, don't use entities, instead use some proxy class. For example RAlbum and RArtist and in your for loop change it.

var albums = from item in externalSource;
 select new RAlbum {
Country = country // Another entity, one that exists in the database
              Name = item["Name"].Value,
       Artist = new RArtist {
                     ExternalId = Int32.Parse(item["ArtistId"].Value),
                     Name = item["ArtistName"].Value
                 }
             };

public static Artist ProcessArtist(RArtist artist, Entities db) {
    var artistLookup = db.Artist.SingleOrDefault(x => x.ExternalId == artist.ExternalId);
    if (artistLookup == null) {
        artistLookup = new Artist {
            ExternalId = artist.ExternalId,
            Name = artist.Name
        };
        db.Artist.AddObject(artistLookup);
        db.SaveChanges();
    }
    return artistLookup;
}


foreach (var album in albums) {
    Album a = new Album();
    // copy properties of a from album
    a.Artist = ProcessArtist(album.Artist, db);
    db.Album.AddObject(a);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文