EF库模式多对多插入 [英] EF repository pattern many to many insert

查看:160
本文介绍了EF库模式多对多插入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有2表:

表管理局:

 公共类管理局
{
   公众诠释ID {获取;设置;}
   公共字符串名称{;设置;}
      ...
}

表代理

 公共类代理
{
  公众诠释ID {获取;设置;}
  公众诠释名字{获得;设置;}
}

和我们有关系多到许多两个表之间:

 公共类AuthorityConfiguration:EntityTypeConfiguration<&管理局GT;
{
    公共AuthorityConfiguration()
        :基地()
    {
        HasKey(p值=> p.ID);        的hasMany(P => p.Agents).WithMany(A => a.Authorities).MAP(MC =>
            {
                mc.MapLeftKey(AuthorityID);
                mc.MapRightKey(AGENTID);
                mc.ToTable(AuthorityAgent);
            });
        ToTable(管理局);    }
}

一切工作正常。
但现在我有一个页面来创建表之间的关联,我需要插入到我的餐桌authorityAgent使用Repository模式的关系。

问题1:我怎样才能获得代理,如果我的DAO正在接收管理局

AuthorityDAO.cs

 公共静态无效InsertAgent(INT authorityID,诠释AGENTID)
    {
        VAR道=新ConcreteDAO<&管理局GT;();        机关机关= dao.Single(P => p.ID.Equals(authorityID));        //我不能这样做,因为关系不存在。
        VAR剂= authority.Agents.Where(P => p.ID.Equals(AGENTID));
        authority.Agents.Add(剂);        dao.Attach(机关);        dao.SaveChanges();    }

我知道我可以在DAO做创建我的上下文,但我会制动的格局,不会吧?

我如何能做到上面的方法?

感谢您。

编辑:我找到了解决办法,但我不知道这是否是更好的方式来做到这一点:

我创建了一个构造函数来我ConcreteDAO传递的ObjectContext和方法来让我的对象上下文:

GenericDAO.cs

 公开的ObjectContext的getContext()
{
     返回_context;
}

ConcreteDAO.cs

 公共ConcreteDAO()
{}公共ConcreteDAO(ObjectContext的上下文)
    :基座(上下文)
{
}

和里面我AuthorityDAO.cs

 公共静态无效InsertAgent(INT authorityID,诠释AGENTID)
 {
     VAR道=新ConcreteDAO<&管理局GT;();
     机关机关= dao.Single(P => p.ID.Equals(authorityID));
     dao.Attach(机关);     VAR daoAgent =新ConcreteDAO<剂>(dao.GetContext());     VAR剂= daoAgent.Single(P => p.ID == AGENTID);     authority.Agents.Add(剂);     dao.SaveChanges();
}


解决方案

我想你,因为你正在使用的存储库模式,而不单位工作模式有这个问题。你的 ConcreteDAO< T> (=实体类型 T ,我想一般存储库)不应该创建一个上下文(=工作单位)。相反,你的消费方式应该明确地创建它,并将其注入到你需要的所有信息库。你最后一种方法则是这样的:

 公共静态无效InsertAgent(INT authorityID,诠释AGENTID)
{
    使用(VAR的UnitOfWork =新的UnitOfWork())//工作单位=背景
    {
        VAR daoAuthority =新ConcreteDAO<&管理局GT;(的UnitOfWork);
        VAR daoAgent =新ConcreteDAO<剂>(的UnitOfWork);        VAR权威= daoAuthority.Single(P => p.ID.Equals(authorityID));
        VAR剂= daoAgent.Single(P => p.ID == AGENTID);        authority.Agents.Add(剂);        unitOfWork.SaveChanges();
    }
}

在哪里变化的关系涉及您需要一个以上的通用存储库许多情况下,但所有工作必须在同一环境中完成的。

可以,顺便说一句,保存因为你知道主键性质并不想改变实体本身,但只有一个关系,从数据库中加载的实体。在这种情况下,你可以附加存根实体工作:

 公共静态无效InsertAgent(INT authorityID,诠释AGENTID)
{
    使用(VAR的UnitOfWork =新的UnitOfWork())
    {
        VAR daoAuthority =新ConcreteDAO<&管理局GT;(的UnitOfWork);
        VAR daoAgent =新ConcreteDAO<剂>(的UnitOfWork);        VAR权威=新局{ID = authorityID,
            代理=新的List<剂>()};
        daoAuthority.Attach(机关);        VAR剂=新代理{ID = AGENTID};
        daoAgent.Attach(剂);        authority.Agents.Add(剂);        unitOfWork.SaveChanges();
    }
}

We have 2 tables:

Table Authority:

public class Authority
{
   public int ID {get;set;}
   public string Name{get;set;}
      ...
}

Table Agents

public class Agent
{
  public int ID{get;set;}
  public int FirstName{get;set;}
}

And we have a relationship many-to-many between these two tables:

public class AuthorityConfiguration : EntityTypeConfiguration<Authority>
{
    public AuthorityConfiguration()
        : base()
    {
        HasKey(p => p.ID);

        HasMany(p => p.Agents).WithMany(a => a.Authorities).Map(mc =>
            {
                mc.MapLeftKey("AuthorityID");
                mc.MapRightKey("AgentID");
                mc.ToTable("AuthorityAgent");
            });


        ToTable("Authority");

    }
}

Everything is working fine. But now I have a page to create an association between the tables and I need to insert into my table "authorityAgent" the relationship using Repository Pattern.

Problem 1: How can I get the Agent if my DAO is receiving an Authority?

AuthorityDAO.cs

public static void InsertAgent(int authorityID, int agentID)
    {
        var dao = new ConcreteDAO<Authority>();

        Authority authority = dao.Single(p => p.ID.Equals(authorityID));

        // I can't do that because the relationship doesn't exist yet.
        var agent = authority.Agents.Where(p => p.ID.Equals(agentID));


        authority.Agents.Add(agent);

        dao.Attach(authority);

        dao.SaveChanges();

    }

I know I can create my context in the DAO to do it, but I will brake the Pattern, won't I?

How can I do the method above?

Thank you.

EDIT: I found a solution but I don't know if it's the better way to do it:

I created a constructor to my ConcreteDAO passing the ObjectContext and a method to get my object context:

GenericDAO.cs

public ObjectContext GetContext()
{
     return _context;
}

ConcreteDAO.cs

public ConcreteDAO()
{

}

public ConcreteDAO(ObjectContext context)
    : base(context)
{
}

And Inside my AuthorityDAO.cs

 public static void InsertAgent(int authorityID, int agentID)
 {
     var dao = new ConcreteDAO<Authority>();
     Authority authority = dao.Single(p => p.ID.Equals(authorityID));
     dao.Attach(authority);

     var daoAgent = new ConcreteDAO<Agent>(dao.GetContext());

     var agent = daoAgent.Single(p => p.ID == agentID);

     authority.Agents.Add(agent);

     dao.SaveChanges();
}

解决方案

I think you are having this problem because you are using the Repository pattern without the Unit Of Work pattern. Your ConcreteDAO<T> (= generic repository for entity type T, I guess) should not create a context (=unit of work). Instead your consuming method should create it explicitly and inject it into all repositories you need. You last method would then look like this:

public static void InsertAgent(int authorityID, int agentID)
{
    using (var unitOfWork = new UnitOfWork()) // unit of work = context
    {
        var daoAuthority = new ConcreteDAO<Authority>(unitOfWork);
        var daoAgent = new ConcreteDAO<Agent>(unitOfWork);

        var authority = daoAuthority.Single(p => p.ID.Equals(authorityID));
        var agent = daoAgent.Single(p => p.ID == agentID);

        authority.Agents.Add(agent);

        unitOfWork.SaveChanges();
    }
}

In many situations where changing relationships are involved you need more than one generic repository, but all work has to be done within the same context.

You can, btw, save to load the entities from the database because you know the primary key properties and don't want to change the entities themselves but only a relationship. In that case you can work with attached "stub" entities:

public static void InsertAgent(int authorityID, int agentID)
{
    using (var unitOfWork = new UnitOfWork())
    {
        var daoAuthority = new ConcreteDAO<Authority>(unitOfWork);
        var daoAgent = new ConcreteDAO<Agent>(unitOfWork);

        var authority = new Authority { ID = authorityID,
            Agents = new List<Agent>() };
        daoAuthority.Attach(authority);

        var agent = new Agent { ID = agentID };
        daoAgent.Attach(agent);

        authority.Agents.Add(agent);

        unitOfWork.SaveChanges();
    }
}

这篇关于EF库模式多对多插入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆