【问题标题】:Inserting relational data with Linq to SQL results in duplicate entry error使用 Linq to SQL 插入关系数据会导致重复输入错误
【发布时间】:2013-11-02 20:45:15
【问题描述】:

我在 Visual Studio 数据库图表编辑器中制定了一个数据库设计,并从中创建了我的所有表。我还创建了一个 Linq to SQL 类并添加了我的表来为每个表创建对象。尝试将新条目插入数据库时​​遇到问题。

例如:

假设我有两张表,Artists 和 Albums。一个艺术家可以有多个专辑(一对多)。专辑有一个 ArtistID 字段,它是 Artist 表中 ArtistID PK 的 FK。它们的 ID 是由数据库自动生成的 GUID。

现在,在我的代码中,我创建了一个新的专辑对象(称为 myAlbum)并将其 Artist 对象设置为数据库中已有的 Artist(myArtist)。

如果我这样做:

DatabaseDataContext context = new DatabaseDataContext();
context.Albums.InsertOnSubmit(myAlbum);
context.SubmitChanges();

我最终得到一个 SqlException 说:“违反主键约束 'PK_Artist'。无法在对象 'dbo.Artist' 中插入重复键。 声明已终止。”

如果我将 myAlbum.Artist 与数据库中已有的 Artist 进行比较,Linq 说它们是相等的,所以它知道它们是同一个对象。

如何让 Linq 插入新的专辑对象并将其链接到数据库中的现有艺术家,而不尝试再次插入艺术家?

【问题讨论】:

  • 什么是pk_Artist列数据类型?
  • 你能把设置艺术家的代码贴出来吗?
  • 我做了一些类似的事情:专辑 myAlbum = new Album("Greatest Hits"); myAlbum.Artist = myArtist;

标签: c# sql linq


【解决方案1】:

显然,您将 Album 的 Artist 属性设置为使用其他 datacontext 实例获取的对象。因此,您的新 DatabaseDataContext“认为”必须插入 Artist。

您可以设置 Album.ArtistId(不是 Artist 对象),也可以在同一数据上下文中获取 Artist 并将专辑添加到其专辑集合中。

顺便说一句,using (var context = new DatabaseDataContext()) { ... } 更好。

【讨论】:

  • 啊!我想你可能在这里有所收获。您是正确的,因为我没有在数据上下文中创建 Artist 对象。这只是我的表的一个子集(为简单起见)。其实我在插入数据库之前就是这样建立大对象关系的。有什么方法可以让 Linq “匹配”数据库中已经存在的对象?
  • 几乎没有。请参阅Attach method。我认为您的情况与那里描述的条件不符。你最好在一个 DataContext 范围内做所有事情,或者使用 Id。
  • 好的。显然我还有一些研究要做。谢谢你的帮助!我认为你让我走上了正确的道路!
【解决方案2】:

您需要先解决重复的主键,通过我的测试,我创建了主表,主键为UNIQUEIDENTIFIER,默认值为(newid())

然后,当您将表拖到 Linq To SQL 类项目中时,将使用您想要的所有内容创建表类,除了:主键列应该将其 Auto Generate Values 设置为 true,但不是!当您的列数据类型为 UNIQUEIDENTIFIER 类型时,默认情况下为 false。 然后我在 MS SQL 中删除了该列并使用 INT 的数据类型重新创建它,将其拖到 Linq to SQL 类中,然后将列属性 Auto Generate Values 设置为 true。

因此,如果您使用UNIQUEIDENTIFIER,则需要手动将Auto Generate Values 属性设置为true。

【讨论】:

    【解决方案3】:

    我认为重复的主键可能是GUID.Empty。如果我的理解是正确的。

    我会想办法解决这个问题。

    pk_artist 列的默认值设置为newid()。这允许主 Kerr 自动生成。

    或者

    将主键显式分配给实体。

    myAlbum.Pk_Artist = GUID.NewGiud();
    context.Albums.InsertOnSubmit(myAlbum);
    

    希望有帮助

    【讨论】:

    • 其实我已经把 pk_arti 的默认值设置为 newid() 并且设置为由数据库自动生成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多