簡體   English   中英

存儲m:n關系時的實體框架DbUpdateException

[英]Entity Framework DbUpdateException when storing m:n relationship

我在使用EF 4.3代碼創建和/或存儲m:n關系時遇到麻煩

因此,第一個實體Publication被定義為具有其他一些內部標量屬性:

    public class Publication : IDataErrorInfo{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int PublicationId { get; set; }

    [InverseProperty("Publications")]
    public virtual ICollection<Group> Groups { get; set; }

和另一個類以相同的方式:

    public class Group : IDataErrorInfo {

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int GroupId { get; set; }

    [InverseProperty("Groups")]
    public ICollection<Publication> Publications { get; set; }

根據許多文章,這應該沒問題。

我發生了幾個問題。 首先:

  • 如果我創建一個新出版物並聲明某些組。 全部存儲到數據庫。 但是,然后我重新啟動程序,同一特定出版物將ICollection設置為null。 因此,有關與組的關系的信息已被刪除。我不知道為什么:(
  • 當我嘗試使用組關系更新現有的發布條目時,將引發DBUpdateException並顯示以下文本:

保存不公開外鍵屬性為其關系的實體時發生錯誤。 EntityEntries屬性將返回null,因為無法將單個實體標識為異常的來源。 通過在實體類型中公開外鍵屬性,可以簡化保存時的異常處理

內部例外是相同的,而內部例外是以下內容:

違反主鍵約束'PK_ Publicat _3AF5D6A10AD2A005'。 無法在對象“ dbo.PublicationGroups”中插入重復鍵。 該語句已終止。

我宣稱該出版物的新價值如下:

var entry = db.Publications.First(a => a.PublicationId == publKey);
entry.Groups = db.Groups.
                Where(a => groupKeys.Contains(a.GroupId)).
                Select(b => b).
                ToList();

其中publKey是已編輯實體的鍵, groupKeys是應該與發布相關的GroupId的列表。

調用db.SaveContext() ,將引發異常

許多文章討論了該主題,但是我沒有找到任何解決方案。 所有示例都使用相同的代碼,但是顯然我缺少了一些東西。 我正在使用SQL Ce 4.0作為持久性數據存儲。

謝謝你們的回答,我從昨天開始就在處理這個問題,但不要為什么會這樣

將組添加到數據庫后,您要致電.Save嗎? 否則,當您嘗試將組添加到發布中時,它們實際上實際上將不在DbSet中。 以下代碼對我有用-也許您可以闡明它與您的代碼有何不同?

public class Publication
{
    public int PublicationId { get; set; }
    public string PublicationName { get; set; }
    public virtual ICollection<Group> Groups { get; set; }
}

public class Group
{
    public int GroupId { get; set; }
    public string GroupName { get; set; }
    public ICollection<Publication> Publications { get; set; }
}

public class Context : DbContext
{
    public DbSet<Publication> Publications { get; set; }
    public DbSet<Group> Groups { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
        Database.SetInitializer(new DropCreateDatabaseIfModelChanges<Context>());

        Context context = new Context();

        // Only add the groups if it's a new database
        if (!context.Groups.Any())
        {
            context.Groups.Add(new Group { GroupName = "Group 1" });
            context.Groups.Add(new Group { GroupName = "Group 2" });
            context.SaveChanges();
        }

        if (context.Publications.Any())
        {
            Console.WriteLine("At startup, P1 is in groups " + String.Join(", ", context.Publications.First().Groups.Select(g => g.GroupName)));
        }

        // Add publication
        Publication p;
        p = new Publication();
        p.Groups = context.Groups.ToList();     // Add to all existing groups
        context.Publications.Add(p);
        context.SaveChanges();

        Console.WriteLine("P1 is in groups " + String.Join(", ", context.Publications.First().Groups.Select(g => g.GroupName)));
    }
}

(代碼已更新為使用SqlCe提供程序)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM