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);
}

有更好的方法吗?

DBContext在对象插入时创建到记录

您的代码不是原子的,如果第二个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();