Code First 迁移创建附加属性
Code First Migration Creating an addition attribute
我正在尝试使用具有以下属性的代码优先 EF 创建 table:
public class HistoryRead
{
[Key]
public int Id { get; set; }
[Required]
public int Book_Id { get; set; }
[Required]
[StringLength(128)]
public string User_Id { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
public virtual Book Book { get; set; }
}
并且我向两个 table 添加了所需的关系:
public partial class AspNetUser
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public AspNetUser()
{
HistoryReads = new HashSet<HistoryRead>();
}
public string Id { get; set; }
[Display(Name = "Email")]
[DataType(DataType.EmailAddress)]
[StringLength(256)]
public string Email { get; set; }
public virtual ICollection<HistoryRead> HistoryReads { get; set; }
}
和:
public partial class Book
{
public Book()
{
HistoryReads = new HashSet<HistoryRead>();
}
[Key]
public int Book_id { get; set; }
[Required]
[Display(Name ="User Name")]
[StringLength(128)]
public string User_ID { get; set; }
public string UrlSlug { get; set; }
[Required]
[Display(Name = "Title Name")]
[StringLength(70,MinimumLength =3)]
public string Book_name { get; set; }
public virtual ICollection<HistoryRead> HistoryReads { get; set; }
}
然后我运行迁移并得到了这个结果!
public override void Up()
{
CreateTable(
"dbo.HistoryReads",
c => new
{
Id = c.Int(nullable: false, identity: true),
Book_Id = c.Int(nullable: false),
User_Id = c.String(nullable: false, maxLength: 128),
AspNetUser_Id = c.String(maxLength: 128),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.AspNetUsers", t => t.AspNetUser_Id)
.ForeignKey("dbo.Book", t => t.Book_Id, cascadeDelete: true)
.Index(t => t.Book_Id)
.Index(t => t.AspNetUser_Id);
}
正如您在迁移生成的代码中看到的那样,我有一个名为 "AspNetUser_Id" 的额外属性,我不需要它,即使我试图删除它并继续我的工作,我也从数据库端得到了一个异常。 .那么如何解决这个问题,谢谢...
这正是我在迁移中所期望的。您的 HistoryRead 中有一个虚拟的 AspNetUser
,EF 会创建一个 AspNetUser_Id 来将其与您的用户相匹配。它不知道您要使用 User_Id 作为键。这就是抛出异常的原因。
它在 book 上起作用的原因是因为它使用 _Id 约定并且它知道它是 book virtual 的外键。
我建议您从模型中删除 User_Id 和 Book_Id。 EF 将处理关系及其所需的外键。这样模型会更干净,你可以通过虚拟访问它。
如所问,如何向对象添加新关系的示例。
var historyObject = dbContext.Set<HistoryRead>().GetById(1);
var bookObject = dbContext.Set<Book>().GetByTitle("Example");
historyObject.Book = bookObject;
dbContext.Set<HistoryRead>().Update(historyObject);
await dbContext.SaveChangesAsync();
我正在尝试使用具有以下属性的代码优先 EF 创建 table:
public class HistoryRead
{
[Key]
public int Id { get; set; }
[Required]
public int Book_Id { get; set; }
[Required]
[StringLength(128)]
public string User_Id { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
public virtual Book Book { get; set; }
}
并且我向两个 table 添加了所需的关系:
public partial class AspNetUser
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public AspNetUser()
{
HistoryReads = new HashSet<HistoryRead>();
}
public string Id { get; set; }
[Display(Name = "Email")]
[DataType(DataType.EmailAddress)]
[StringLength(256)]
public string Email { get; set; }
public virtual ICollection<HistoryRead> HistoryReads { get; set; }
}
和:
public partial class Book
{
public Book()
{
HistoryReads = new HashSet<HistoryRead>();
}
[Key]
public int Book_id { get; set; }
[Required]
[Display(Name ="User Name")]
[StringLength(128)]
public string User_ID { get; set; }
public string UrlSlug { get; set; }
[Required]
[Display(Name = "Title Name")]
[StringLength(70,MinimumLength =3)]
public string Book_name { get; set; }
public virtual ICollection<HistoryRead> HistoryReads { get; set; }
}
然后我运行迁移并得到了这个结果!
public override void Up()
{
CreateTable(
"dbo.HistoryReads",
c => new
{
Id = c.Int(nullable: false, identity: true),
Book_Id = c.Int(nullable: false),
User_Id = c.String(nullable: false, maxLength: 128),
AspNetUser_Id = c.String(maxLength: 128),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.AspNetUsers", t => t.AspNetUser_Id)
.ForeignKey("dbo.Book", t => t.Book_Id, cascadeDelete: true)
.Index(t => t.Book_Id)
.Index(t => t.AspNetUser_Id);
}
正如您在迁移生成的代码中看到的那样,我有一个名为 "AspNetUser_Id" 的额外属性,我不需要它,即使我试图删除它并继续我的工作,我也从数据库端得到了一个异常。 .那么如何解决这个问题,谢谢...
这正是我在迁移中所期望的。您的 HistoryRead 中有一个虚拟的 AspNetUser
,EF 会创建一个 AspNetUser_Id 来将其与您的用户相匹配。它不知道您要使用 User_Id 作为键。这就是抛出异常的原因。
它在 book 上起作用的原因是因为它使用 _Id 约定并且它知道它是 book virtual 的外键。
我建议您从模型中删除 User_Id 和 Book_Id。 EF 将处理关系及其所需的外键。这样模型会更干净,你可以通过虚拟访问它。
如所问,如何向对象添加新关系的示例。
var historyObject = dbContext.Set<HistoryRead>().GetById(1);
var bookObject = dbContext.Set<Book>().GetByTitle("Example");
historyObject.Book = bookObject;
dbContext.Set<HistoryRead>().Update(historyObject);
await dbContext.SaveChangesAsync();