简体   繁体   English

MVC EF-System.Data.Entity.Infrastructure.DbUpdateException

[英]MVC EF - System.Data.Entity.Infrastructure.DbUpdateException

I have two models : UserProfile 我有两个模型:UserProfile

public class UserProfile
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }
    public virtual ICollection<UserPost> UserPost { get; set; }
}

UserPost: UserPost:

public class UserPost
{  
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public string Id { get; set; }
   public string PostTitle { get; set; }
   public virtual UserProfile UserProfile { get; set; }
   public string Contents { get; set; }
}

UserProfile has a one-to-one relationship with AspNetUser. UserProfile与AspNetUser具有一对一关系。

UserProfile has a one-to-many relationship with UserPost. UserProfile与UserPost具有一对多关系。

When I'm adding UserPost to the database in the Create method in my controller I get a System.Data.Entity.Infrastructure.DbUpdateException 当我在控制器的Create方法中将UserPost添加到数据库时,我得到了System.Data.Entity.Infrastructure.DbUpdateException

    [HttpPost]
    [ValidateAntiForgeryToken]
    [Authorize]
    public ActionResult Create([Bind(Include = "PostTitle, Content")] UserPost post)
    {
        if (ModelState.IsValid)
        {

            UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
            var user = UserManager.FindById(User.Identity.GetUserId());
            post.UserProfile = user.UserProfile;
            db.UserPosts.Add(post);
            db.SaveChanges();//error here
            return RedirectToAction("Index");
        }

        return View(post);
    }

System.Data.Entity.Infrastructure.DbUpdateException occurred HResult=0x80131501 Message=An error occurred while saving entities that do not expose foreign key properties for their relationships. 发生System.Data.Entity.Infrastructure.DbUpdateException HResult = 0x80131501消息=在保存不为其关系公开外键属性的实体时发生错误。 The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. EntityEntries属性将返回null,因为无法将单个实体标识为异常的来源。 Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. 通过在实体类型中公开外键属性,可以简化保存时的异常处理。 See the InnerException for details. 有关详细信息,请参见InnerException。

Inner Exception 1: UpdateException: An error occurred while updating the entries. 内部异常1:UpdateException:更新条目时发生错误。 See the inner exception for details. 有关详细信息,请参见内部异常。

Inner Exception 2: SqlException: Cannot insert the value NULL into column 'Id', table 'aspnet-project12017.dbo.UserPosts'; 内部异常2:SqlException:无法将值NULL插入表'aspnet-project12017.dbo.UserPosts'的列'Id'中; column does not allow nulls. 列不允许为空。 INSERT fails. INSERT失败。 The statement has been terminated. 该语句已终止。

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] means that the column marked with such attribute expected having auto-generated value from DBMS, and as a general convention that EF treats string & uniqueidentifier (GUID) columns as non auto-incremented, hence those columns value must be assigned in another way (ie by constructor assignment). [DatabaseGenerated(DatabaseGeneratedOption.Identity)]表示标记有该属性的列应具有从DBMS自动生成的值,并且作为常规惯例,EF将string和唯一uniqueidentifier (GUID)列视为非自动递增,因此这些列的值必须以其他方式分配(即通过构造函数分配)。

Common approach to solve null problem for primary key auto-incremented identity column is simply set it to numeric data type (eg int ): 解决主键自动递增标识列的空值问题的常见方法是将其设置为数值数据类型(例如int ):

public class UserPost
{  
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int Id { get; set; } // change to numeric data type
   public string PostTitle { get; set; }
   public virtual UserProfile UserProfile { get; set; }
   public string Contents { get; set; }
}

Then, when performing migrations, do these steps: 然后,在执行迁移时,请执行以下步骤:

  1. Sometimes EF expects by default that you're trying to insert into identity column. 有时,EF默认情况下会期望您尝试插入“身份”列。 If this happens, set StoreGeneratedPattern.None & DatabaseGenerationOption.None to UserPost.Id temporarily: 如果发生这种情况,请将StoreGeneratedPattern.NoneDatabaseGenerationOption.None暂时设置为UserPost.Id

     protected void OnModelCreating(DbModelBuilder modelBuilder) { // other entities modelBuilder.Entity<UserPost>() .HasKey(p => p.Id) .Property(p => p.Id) .StoreGeneratedPattern = StoreGeneratedPattern.None; // other entities } 
  2. Ensure that the model has been modified to include actual Id property (try to delete UserPost table in DB when required). 确保已将模型修改为包括实际的Id属性(必要时尝试在DB中删除UserPost表)。

  3. Run migration through Package Manager Console as this: 通过Package Manager控制台运行迁移,如下所示:

     Add-Migration "Set Id as Identity Specification" 
  4. In a generated class from DbMigration you will see two methods: Up() and Down() . DbMigration生成的类中,您将看到两个方法: Up()Down() Modify Up() part to set int datatype there (and re-run migration process when required): 修改Up()部分以在那里设置int数据类型(并在需要时重新运行迁移过程):

     public override void Up() { CreateTable( "dbo.UserPost", c => new { Id = c.Int(nullable: false, identity: true), PostTitle = c.String(), Contents = c.String(), }) .PrimaryKey(t => t.Id); } 

If you still want string Id column as primary key for UserPost , you need to set it as [DatabaseGenerated(DatabaseGeneratedOption.None)] and assign values manually from class constructor (note that generated values must be unique at all or EF will tell you "cannot insert duplicate key in object"): 如果您仍然希望将字符串Id列作为UserPost主键, UserPost需要将其设置为[DatabaseGenerated(DatabaseGeneratedOption.None)]并从类构造函数中手动分配值(请注意,生成的值必须完全唯一,否则EF会告诉您“无法在对象中插入重复的密钥”):

public class UserPost
{
    public UserPost()
    {
        Id = [[autogenerated value here]];
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public string Id { get; set; }

    // other properties
}

Related issues: 相关问题:

MVC5 EF6 Seed Method: Cannot insert NULL into column 'Id' table AspNetUsers MVC5 EF6种子方法:无法将NULL插入列“ Id”表中的AspNetUsers

Cannot insert the value NULL into column 'Id' (Database first) 无法将值NULL插入列“ Id”(数据库优先)

Code first - Cannot insert the value NULL into column 'Id' 代码优先-无法将值NULL插入列'Id'

Entity Framework Cannot insert the value NULL into column Identity Specification set to No 实体框架无法将值NULL插入设置为No的列Identity Specification中

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 System.Data.Entity.Infrastructure.DbUpdateException - System.Data.Entity.Infrastructure.DbUpdateException System.Data.Entity.Infrastructure.DbUpdateException问题 - System.Data.Entity.Infrastructure.DbUpdateException Issue 发生System.Data.Entity.Infrastructure.DbUpdateException - System.Data.Entity.Infrastructure.DbUpdateException occurred EF-&gt; System.Data.Entity.Infrastructure.DbUpdateException-&gt;主键Guid.Empty约束-&gt;默认绑定= newsequentialid() - EF -> System.Data.Entity.Infrastructure.DbUpdateException -> Primary Key Guid.Empty Constraint -> Default Binding = newsequentialid() 如何解决 System.Data.Entity.Infrastructure.DbUpdateException - How to solve System.Data.Entity.Infrastructure.DbUpdateException 递归树方法上的System.Data.Entity.Infrastructure.DbUpdateException - System.Data.Entity.Infrastructure.DbUpdateException on recursive Tree method 将数据添加到数据库(错误:System.Data.Entity.Infrastructure.DbUpdateException) - Adding Data to Database (Error: System.Data.Entity.Infrastructure.DbUpdateException) EntityFramework.dll 中发生“System.Data.Entity.Infrastructure.DbUpdateException” - 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll 如何避免System.Data.Entity.Infrastructure.DbUpdateException - How to avoid System.Data.Entity.Infrastructure.DbUpdateException 发生类型为“ System.Data.Entity.Infrastructure.DbUpdateException”的异常 - An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM