Entity framework 首先通过实体框架代码以多对多关系附加到现有对象

Entity framework 首先通过实体框架代码以多对多关系附加到现有对象,entity-framework,ef-code-first,many-to-many,asp.net-web-api2,Entity Framework,Ef Code First,Many To Many,Asp.net Web Api2,我正在使用WebAPI2和EF6代码开发RESTAPI,首先从上的指南开始 我基本上也在做同样的事情,有一个多对多的关系,当我创建一个对象时,让我们称之为a,我在帖子中包含一个B对象数组作为Bs变量。它们都是在最初的帖子中按预期创建的,但是,当我添加第二个对象a时,它应该链接到一个或多个与第一个对象a相同的B,而不是与现有的B匹配,它尝试创建新的B,但是由于B的名称有限制,所以这不起作用。如何确保它不会每次尝试创建新对象B,而是链接到现有对象B(如果有) 下面是更详细的示例 我有两个模型,我们称

我正在使用WebAPI2和EF6代码开发RESTAPI,首先从上的指南开始 我基本上也在做同样的事情,有一个多对多的关系,当我创建一个对象时,让我们称之为a,我在帖子中包含一个B对象数组作为Bs变量。它们都是在最初的帖子中按预期创建的,但是,当我添加第二个对象a时,它应该链接到一个或多个与第一个对象a相同的B,而不是与现有的B匹配,它尝试创建新的B,但是由于B的名称有限制,所以这不起作用。如何确保它不会每次尝试创建新对象B,而是链接到现有对象B(如果有)

下面是更详细的示例

我有两个模型,我们称它们为A和B。它们有多对多的关系

public class A
{
    public int Id { get; set; }
    [Required, StringLength(100), Index("IDX_Name", 2, IsUnique = true)]
    public string Name { get; set; }
    [StringLength(300)]
    public string Description { get; set; }

    public ICollection<B> Bs{ get; set; }
}
它起作用了,FirstA和FirstB都被创建了。 如果我发布第二个a,它也链接到第一个B对象

    {
    "Name": "SecondA",
    "Description": "SecondADesc",
    "Bs" : [{"Name":"SecondB"},{"Name":"FirstB"}]
    }
它将不再寻找第一个B,而是尝试再次创建它。这是由于约束

我的第一个猜测是,我应该在第二篇文章中使用ID:s。比如:

    {
    "Name": "SecondA",
    "Description": "SecondADesc",
    "Bs" : [{"Id":"1"},{"Name":"FirstB"}]
    }
但这也不起作用

实现这一点的唯一方法是替换控制器的脚手架代码,并手动检查Bs中的每个对象(如果已经存在)

基本上这是一个“标签到帖子的问题”。。。 我已经研究了附加的与分离的数据主题,并阅读了有关该问题的文章,但没有找到一个答案,即我可以理解这是否可以通过一些适当的注释自动完成,或者是否必须在控制器中“手动”完成


提前谢谢

这次没有太多回应, 最后循环并手动检查现有条目,如下所示

[ResponseType(typeof(A))]
public async Task<IHttpActionResult> PostGame(A a)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    foreach (var asd in a.Bs.ToList())
    {
    var t = db.Bs.FirstOrDefault(a => a.Name == asd.Name);
      if (t != null)
      {
        a.Bs.Remove(asd);
        a.Bs.Add(t);
      }
    }
    db.As.Add(a);
    await db.SaveChangesAsync();

    return CreatedAtRoute("DefaultApi", new { id = a.Id }, a);

}
[ResponseType(typeof(A))]
公开异步任务赛后(A)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
foreach(a.Bs.ToList()中的var asd)
{
var t=db.Bs.FirstOrDefault(a=>a.Name==asd.Name);
如果(t!=null)
{
a、 拆除(asd);
a、 Bs.添加(t);
}
}
db.As.Add(a);
等待db.saveChangesSync();
返回CreatedAtRoute(“DefaultApi”,新的{id=a.id},a);
}
尽管如此,我还是忍不住觉得一定有比这更好的办法

    {
    "Name": "SecondA",
    "Description": "SecondADesc",
    "Bs" : [{"Name":"SecondB"},{"Name":"FirstB"}]
    }
    {
    "Name": "SecondA",
    "Description": "SecondADesc",
    "Bs" : [{"Id":"1"},{"Name":"FirstB"}]
    }
[ResponseType(typeof(A))]
public async Task<IHttpActionResult> PostGame(A a)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    foreach (var asd in a.Bs.ToList())
    {
    var t = db.Bs.FirstOrDefault(a => a.Name == asd.Name);
      if (t != null)
      {
        a.Bs.Remove(asd);
        a.Bs.Add(t);
      }
    }
    db.As.Add(a);
    await db.SaveChangesAsync();

    return CreatedAtRoute("DefaultApi", new { id = a.Id }, a);

}