DBContext在对象插入时创建到记录
本文关键字:创建 记录 插入 对象 DBContext | 更新日期: 2023-09-27 18:00:35
我正在寻找一个好的设计来完成以下任务。
在我们使用实体框架(和代码优先)的C#MVC项目中,为了进行本次对话,我们有3个表。资源、配置文件、组织。
当我们添加Profile记录时,我们首先需要创建一个Resource记录,并使用ResourceId作为ProfileId。添加组织也是如此。
我不确定是否有好的方法来处理这个问题。现在我们做这样的事情:
public IHttpActionResult PostProfile(Profile profile)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var res = new Resource();
_db.Resource.Add(res);
_db.SaveChanges();
profile.ProfileId = res.ResourceId;
_db.Profile.Add(profile);
_db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = profile.ProfileId }, profile);
}
有更好的方法吗?
您的代码不是原子的,如果第二个SaveChanges崩溃会发生什么,例如因为数据库没有响应,。。。
最好只使用一个SaveChanges()
var res = new Resource();
_db.Resource.Add(res);
profile.ProfileId = res.ResourceId;
_db.Profile.Add(profile);
_db.SaveChanges();
其中的一部分我认为最好用不同的方式对对象进行建模,而不是在Profile中有Resource的ID,拥有整个对象,这样你就可以利用懒惰加载,一个更强大的查询。
public class Resource()
{
public int ID { get; set; }
.......
}
public class Profile()
{
public int ID { get; set; }
.....
public virtual Resource Resource { get; set; }
}
以及添加新项目的代码
var profile = new Profile()
{
Resource = new Resource(),
....
}
_db.Profile.Add(profile);
_db.SaveChanges();
如果您的Profile
类需要ResourceId
,您可以添加一个新属性:
public class Profile
{
public int Id { get; set; }
public int ResourceId { get; set; }
public virtual Resource Resource { get; set; }
...
}
virtual
关键字用于管理更改跟踪和延迟加载。
在数据库上下文中,OnModelCreating()
方法链接两个字段:
modelBuilder.Entity<Profile>().HasRequired(x => x.Profile)
.WithMany().HasForeignKey(x => x.ProfileId);
如果需要,在HasRequired()
上使用HasOptional()
。有关此主题的更多信息,请访问MSDN-使用Fluent API配置关系。
现在,您可以在一个数据库操作中添加这两个对象:
var _profile = new Profile();
// set more _profile properties
_profile.Resource = new Resource
{
// set resource properties, but
// exclude the Id property
};
_db.Profile.Add(_profile);
_db.SaveChanges();