1

我在创建和/或存储与 EF 4.3 Code first 的 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 设置为空。因此与集团的关系信息已被删除。我不知道为什么:(
  • 当我尝试使用 Group 关系更新现有的 Publication 条目时,会引发 DBUpdateException 并带有以下文本:

保存不为其关系公开外键属性的实体时发生错误。EntityEntries 属性将返回 null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地处理保存时的异常

在内部异常中是一样的,在这个内部异常中是这样的:

违反 PRIMARY KEY 约束“ 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();

wherepublKey是已编辑实体的键,groupKeys是应该与发布相关的 GroupId 的列表。

调用后db.SaveContext()抛出异常

这个话题已经被很多文章覆盖了,但我没有找到任何解决方案。所有示例都使用相同的代码,但显然我遗漏了一些东西。我使用 SQL Ce 4.0 作为持久性数据存储。

谢谢大家的回答,我从昨天开始就在处理它,但不知道为什么会发生这种情况

4

1 回答 1

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 提供程序)

于 2012-05-19T08:49:50.790 回答