EF存储库模式多对多插入
我们有 2 个表:
表 Authority:
public class Authority
{
public int ID {get;set;}
public string Name{get;set;}
...
}
表 Agents
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");
}
}
一切正常。 但现在我有一个页面来创建表之间的关联,我需要使用存储库模式将关系插入到我的表“authorityAgent”中。
问题 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();
}
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您遇到这个问题是因为您使用的是存储库模式而不是工作单元模式。您的
ConcreteDAO
(=实体类型T
的通用存储库,我猜)不应创建上下文(=工作单元)。相反,您的使用方法应该显式创建它并将其注入到您需要的所有存储库中。最后一种方法将如下所示:在许多涉及更改关系的情况下,您需要多个通用存储库,但所有工作都必须在同一上下文中完成。
顺便说一句,您可以保存以从数据库加载实体,因为您知道主键属性并且不想更改实体本身而只想更改关系。在这种情况下,您可以使用附加的“存根”实体:
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 typeT
, 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: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: