Jiv*_*man 0 c# asp.net-mvc ef-code-first entity-framework-6
我在我的域中有一个类似于以下的一对多关系:
public class Movie
{
public int MovieID { get; set; }
public string MovieName { get; set; }
public virtual ICollection<MovieCategory> Categories { get; set; }
}
public class MovieCategory
{
[Key, ForeignKey("Movie")]
public int MovieID { get; set; }
[Key, ForeignKey("Category")]
public int CategoryID { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime DateCreated { get; set; }
public virtual Movie Movie { get; set; }
public virtual Category Category { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
通过GETDATE()插入新电影(并在一堆复选框中检查某些类别)在 SQL 中设置 DateCreated 字段。那部分工作正常。
但是,在编辑电影时,我需要能够更新电影类别的选择(这意味着添加一些和/或删除其他的,基于用户对复选框中的选择所做的操作)。我试过这个:
public ActionResult Edit(MovieEditViewModel model)
{
var movie = db.Movies.Find(model.MovieID);
//clear out all previously selected categories
movie.Categories.Clear();
//add the list of selected categories from just-edited movie
foreach(var catID in model.selectedCategories)
{
movie.Categories.Add(new MovieCategory { CategoryID = catID });
}
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
我猜 EF 足够聪明,可以弄清楚哪些类别需要删除,哪些需要添加,哪些需要修改。
唯一的问题是,对于它正在修改的字段,它会尝试修改每个字段,包括 DateCreated 字段,并且由于该字段只能在插入期间被触摸(即“身份”),因此会导致此错误:
"Modifying a column with the 'Identity' pattern is not supported. Column: 'DateCreated'. Table: 'CodeFirstDatabaseSchema.MovieCategory'."
Run Code Online (Sandbox Code Playgroud)
有什么想法可以解决这个问题吗? 我想要做的就是允许某人编辑一部电影,在编辑过程中可能会或可能不会修改电影类别列表,并且 DB 中的表 MovieCategory 需要准确反映编辑的选择。
我也尝试添加这个,但没有改变:
foreach(var category in movie.Categories)
{
db.Entry(category).Property(c => c.DateCreated).IsModified = false;
}
Run Code Online (Sandbox Code Playgroud)
DatabaseGeneratedOption.Identity用于标识列。这些也是自动生成的,但它们永远不会被修改,因为这些列通常用作主键。
您应该将选项更改为
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime DateCreated { get; set; }
Run Code Online (Sandbox Code Playgroud)
执行此操作时,EF 将忽略插入和更新语句中的属性,并在这些语句之后立即从数据库中读取其值。
如果您这样做,您的代码应该可以正常运行。
旁注,声明
db.Entry(movie).State = EntityState.Modified;
Run Code Online (Sandbox Code Playgroud)
是多余的,因为它只影响movie的标量属性,而不影响它的Categories。并且movie本身没有被修改。
| 归档时间: |
|
| 查看次数: |
1802 次 |
| 最近记录: |