我希望找到一个很好的设计来完成以下任务。
在我们使用实体框架(和codefirst)的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);
}
有更好的方法吗?
答案 0 :(得分:1)
如果第二个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();
答案 1 :(得分:0)
如果您的Profile
课程需要ResourceId
,您可以添加新的媒体资源:
public class Profile
{
public int Id { get; set; }
public int ResourceId { get; set; }
public virtual Resource Resource { get; set; }
...
}
virtual
关键字用于管理更改跟踪和延迟加载。
在db上下文OnModelCreating()
方法中链接两个字段:
modelBuilder.Entity<Profile>().HasRequired(x => x.Profile)
.WithMany().HasForeignKey(x => x.ProfileId);
而是HasRequired()
使用HasOptional()
,如果需要的话。有关此主题的更多信息,请访问MSDN - Configuring Relationships with the 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();