Шаблон репозитория EF много ко многим вставить - PullRequest
3 голосов
/ 20 декабря 2011

У нас есть 2 таблицы:

Таблица доступа:

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

Таблица агентов

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

И у нас есть отношения многие ко многим между этими двумя таблицами:

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");

    }
}

Все работает нормально. Но теперь у меня есть страница для создания связи между таблицами, и мне нужно вставить в мою таблицу «authorAgent» связь, используя шаблон репозитория.

Проблема 1: Как я могу получить агента, если мой DAO получает полномочия?

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();

    }

Я знаю, что могу создать свой контекст в DAO, чтобы сделать это, но я буду тормозить Шаблон, не так ли?

Как я могу сделать описанный выше метод?

Спасибо.

РЕДАКТИРОВАТЬ: Я нашел решение, но я не знаю, если это лучший способ сделать это:

Я создал конструктор для моего ConcreteDAO, передав ObjectContext и метод для получения контекста моего объекта:

GenericDAO.cs

public ObjectContext GetContext()
{
     return _context;
}

ConcreteDAO.cs

public ConcreteDAO()
{

}

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

И внутри моего 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();
}

1 Ответ

3 голосов
/ 20 декабря 2011

Я думаю, что у вас возникла эта проблема, потому что вы используете шаблон Repository без шаблона Unit Of Work. Ваш ConcreteDAO<T> (= общий репозиторий для типа сущности T, я полагаю) не должен создавать контекст (= единицу работы). Вместо этого ваш метод потребления должен создать его явно и внедрить во все нужные вам репозитории. Ваш последний метод будет выглядеть следующим образом:

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();
    }
}

Во многих ситуациях, когда требуется изменение отношений, вам требуется более одного общего хранилища, но вся работа должна выполняться в одном и том же контексте.

Между прочим, вы можете сохранить, чтобы загрузить объекты из базы данных, потому что вы знаете свойства первичного ключа и не хотите изменять сами объекты, а только отношения. В этом случае вы можете работать с присоединенными «заглушками» сущностями:

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();
    }
}
...