如何使用实体框架添加一对多关系

时间:2014-09-15 00:45:39

标签: entity-framework

我的网络表单项目中有一对多的关系。并且总是得到相同的错误:"实体对象不能被ientitychangetracker的多个实例引用" 。 如何解决此问题,如何使用实体框架在一对多关系中添加项?以下是示例代码:

        MusicianManager mm = new MusicianManager();
        Musician m = new Musician();
        m.MusicianName = txtMusicianName.Text;
        m.MusicianSurname = txtMusicianSurname.Text;
        m.MusicianInstrument = txtInstrument.Value;

        CountryManager cm = new CountryManager();
        m.Country = cm.GetById(Convert.ToInt32(drpLstCountry.SelectedValue));

        int id = mm.Add(m);

CountryManager类:

using ROCK.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ROCK.DataAccess
{
public class CountryManager
{
    public Country GetById(int id)
    {
        RockolektifDatabaseEntities rde = new RockolektifDatabaseEntities();
        return rde.Countries.FirstOrDefault(c => c.CountryId == id);
    }
}
}

MusicianManager类:

using ROCK.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ROCK.DataAccess
{
public class MusicianManager
{
    public int Add(Musician m)
    {
        RockolektifDatabaseEntities rde = new RockolektifDatabaseEntities();
        rde.Musicians.Add(m);
        rde.SaveChanges();
        List<Musician> m2 = rde.Musicians.OrderByDescending(mm => mm.MusicianId).Take(1).ToList();
        foreach (var item in m2)
        {
            return item.MusicianId;
        }
        return -1;

    }
}
}

我使用整个设计 - (dataaccess,entity和userinterface。)

1 个答案:

答案 0 :(得分:0)

您必须了解Add方法将触发实体框架执行DetectChanges操作。此操作将修复所有关系:即,它将调整新MusicianCountry的导航属性。

通过致电Add,新的Musician与您在DbContext内初始化的CountryManager相关联,同时它也会将其连接到DbContextMusicianManager内初始化。为了使其成功,至少其中一个上下文必须禁用更改跟踪。

如果您需要更多帮助,请向我们展示经理的构造函数和GetById函数的代码。

看到更新的代码后,我建议您更改行:

RockolektifDatabaseEntities rde = new RockolektifDatabaseEntities();

使用块:

using(RockolektifDatabaseEntities rde = new RockolektifDatabaseEntities())
{
    //the code of the method
    return //the entity
}

这将消除关于由两个上下文跟踪的实体的异常。但可能会出现新的例外情况。

重构到using块后(你必须做什么,否则你的应用程序将开始泄漏内存)我会将代码重写为:

MusicianManager mm = new MusicianManager();
    Musician m = new Musician();
    m.MusicianName = txtMusicianName.Text;
    m.MusicianSurname = txtMusicianSurname.Text;
    m.MusicianInstrument = txtInstrument.Value;

    CountryManager cm = new CountryManager();
    var country= cm.GetById(Convert.ToInt32(drpLstCountry.SelectedValue));
    if(country!=null) m.CountryId=country.CountryId;
    int id = mm.Add(m);    

这假设Musician的导航属性CountryId

有一个名为Country.的外键