在Entity Framework中考虑这个简单的一对多关系。一个组织拥有许多产品。
public class Product
{
public int Id { get; set; }
[StringLength(20)]
public string Title { get; set; }
[StringLength(300)]
public string Description { get; set; }
public float Price { get; set; }
public DateTime CreationDate { get; set; }
public virtual Organisation Organisation { get; set; }
public Product()
{
CreationDate = DateTime.Now;
}
}
public class Organisation
{
public int Id { get; set; }
[StringLength(20)]
public string Title { get; set; }
[StringLength(400)]
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
如果我有一个(post)api调用,接受正文中的原始数据(json格式的文本),这允许用户在同一个调用中创建一个组织和任意数量的产品。如何使用Entity Framework将这些数据正确保存到数据库中?
据我所知,我正在使用延迟加载(由于在模型中设置关系时使用虚拟关键字),所以不应该自动处理关系?如果我保存数据,如下面的控制器操作(调用后的控制器操作)。它会起作用吗?如果没有,那么使用Entity Framework保存包含另一个模型列表的模型的适当/最佳实践方法是什么。
public IHttpActionResult CreateOrganisation(Organisation org)
{
db.Organisations.Add(org);
db.SaveChanges();
return Ok(org);
}
真的似乎无法在文档中找到这个?
好吧,我没有时间尝试它,但是看看你的代码,我看到有一些建议,如果你正在寻找最好的做法,我可能会指向你,即使这些也没有回答你的问题:
public async Task<IHttpActionResult> CreateOrganisation(Organisation org)
我希望这些建议可以帮到你。
既然你要求“最佳实践”,我会告诉你一个技术,当EF对象图的处理有点时,我必须回过头来处理这个技术,我们会说“iffy”吗?
首先,每个物理存储的实体具有相应的DTO对象。 ViewModel(MVVM-speak)的一部分是该View的必要DTO对象。添加了其他字段以便为每个实体传达State(UI所做的)。它看起来像这样:
public class ProductDTO {
// Same fields, mostly
public string Action { get; set; } // A, C, D
}
public class OrganizationDTO {
// Same fields except children
public ICollection<ProductDTO> Products { get; set; }
public string Action { get; set; }
}
基于顶级DTO,POST,PUT或DELETE(A,C,D)中的非空白动作。 UI设置每个实体的状态。对孩子的修改被视为对父母的“改变”。
然后在后端的CRUD方法中...不可否认,这是大锤的方法。
public class OrganizationRepository : whatever interfaces {
public void Add (OrganizationDTO newOrg) {
if (newOrg.Action != "A") // Why are you here?
throw an exception (bad request)
context.Organizations.Add(Map DTO to entity here);
foreach (var item in newOrg.Products) {
switch (item.Action)
case "A":
ProductRepository.Add(item,newOrg.Id);
break;
case "C":
ProductRepository.Update(item,newOrg.Id);
break;
case "D":
ProductRepository.Delete(item);
break;
}
context.SaveChanges();
}
public void Update (OrganizationDTO oldOrg) {
if (newOrg.Action != "C") // Why are you here?
throw an exception (bad request)
context.Organizations.Attach(Map DTO to entity here);
foreach (var item in newOrg.Products) {
switch (item.Action)
case "A":
ProductRepository.Add(item,newOrg.Id);
break;
case "C":
ProductRepository.Update(item,newOrg.Id);
break;
case "D":
ProductRepository.Delete(item);
break;
}
context.SaveChanges();
return Ok();
}
}
这不是工作/测试代码。只是粗糙的袖口。必须在添加时处理FK。添加您的映射技术。处理碰撞,尝试/捕捉等
我认为你的代码不能自我解释。 如果我是一个开发人员,看看你在这里发布的方法,我根本不明白我有可能发送嵌套数据。
我会对对象“org”的Products集合进行迭代,然后将它们添加到EF集合中,然后将组织添加到自己的集合中。
然后,显然,SaveChanges()。
这可以清楚地区分接受嵌套对象的这种方法,以及另一种不支持嵌套对象的方法,并简单地保存我的新空组织。