一个存储库应该调用另一个存储库吗?或者存储库应该调用服务层吗?
我正在想办法解决这个问题。我必须将一些数据插入到 2 个表中,我们称它们为表 A 和表 B。
Table A has these columns
AId<PK>
A1
A2
A3
Table B has
AId<PK>
A1
B2
B3
B4
现在我的第一个问题是另一个存储库是否应该调用另一个存储库?我认为这不能解决我当前的问题,但我只是想知道这一点以供将来参考?
现在谈谈我的问题。
当我在存储库层(TableARepository)中调用 create 来创建表 A 时。我也立即创建了 tableB 的字段。
// linq to sql.
TableA myATable = new TableA();
dbContext.myATable.A1 = "hi"; // all these values would come from parameters.
dbContext.myATable.A2 = "bye";
dbContext.myATable.A3 = "go";
dbContext.myATable.insertOnSubmit(TableA);
dbContext.SubmitChanges();
TableB myBTable = new TableB();
dbContext.myBTable.AId = myATable.AId;
dbContext.myBTable.A1 = myATable.A1;
dbContext.myBTable.B2 = "2";
dbContext.myBTable.B3 = "3";
dbContext.myBTable.B4 = "4";
dbContext.myATable.insertOnSubmit(TableB);
dbContext.SubmitChanges();
所以我认为这很好,我认为我不需要为此层或服务层调用 myBTable 存储库(以创建 tableB)。
现在问题来了。当且仅当 TableB 表不等于“hi”时,才应将信息插入到该表中。
so param1 != "hi" // insert
param1 == "hi" // ignore and only insert table A
所以这意味着我必须像这样包装我的 TableB
if(param1 != "hi")
{
TableB myBTable = new TableB();
dbContext.myBTable.AId = myATable.AId;
dbContext.myBTable.A1 = myATable.A1;
dbContext.myBTable.B2 = "2";
dbContext.myBTable.B3 = "3";
dbContext.myBTable.B4 = "4";
dbContext.myATable.insertOnSubmit(TableB);
dbContext.SubmitChanges();
}
现在我不确定我是否应该在这里这样做,因为这看起来几乎像业务逻辑。但同时我不确定如何执行此业务逻辑,因为无论哪种方式,我仍然必须传递要插入到 create 方法中的值,即使它为 null(A1 是一个可为 null 的字段)。
那么我应该调用tableB服务层传递TableA.Id,A1并检查A1是什么。如果好,那么转到 TableB 存储库并以这种方式插入它?
所以TableARepostiory -> TableB服务层-> TableBRepository(如果发现该值!=“hi”)。
所以我不知道该怎么办。
I am trying to figure out how to tackle this problem. I have to insert some data into 2 tables lets call them Table A and Table B.
Table A has these columns
AId<PK>
A1
A2
A3
Table B has
AId<PK>
A1
B2
B3
B4
Now my first question was should another repository call another repository? I don't think this will solve my current problem but I just want to know this for future reference?
Now onto my problem.
when I call a create in my repository layer(TableARepository) to Create Table A. I create right away the fields for tableB too.
// linq to sql.
TableA myATable = new TableA();
dbContext.myATable.A1 = "hi"; // all these values would come from parameters.
dbContext.myATable.A2 = "bye";
dbContext.myATable.A3 = "go";
dbContext.myATable.insertOnSubmit(TableA);
dbContext.SubmitChanges();
TableB myBTable = new TableB();
dbContext.myBTable.AId = myATable.AId;
dbContext.myBTable.A1 = myATable.A1;
dbContext.myBTable.B2 = "2";
dbContext.myBTable.B3 = "3";
dbContext.myBTable.B4 = "4";
dbContext.myATable.insertOnSubmit(TableB);
dbContext.SubmitChanges();
So I think this is fine and I don't think I would need to call myBTable repository(to create tableB) for this or a service layer.
Now here is the problem. TableB table should only have the information inserted into this table if and only if it is not equal to "hi".
so param1 != "hi" // insert
param1 == "hi" // ignore and only insert table A
so this would mean I would have to wrap my TableB like this
if(param1 != "hi")
{
TableB myBTable = new TableB();
dbContext.myBTable.AId = myATable.AId;
dbContext.myBTable.A1 = myATable.A1;
dbContext.myBTable.B2 = "2";
dbContext.myBTable.B3 = "3";
dbContext.myBTable.B4 = "4";
dbContext.myATable.insertOnSubmit(TableB);
dbContext.SubmitChanges();
}
Now I am not sure if I should be doing this here since this seems almost like business logic. yet at the same time I am not sure how to do this business logic since either way I still have to pass in the value to insert into the create method even if it is null(A1 is a nullable field).
So should I call the tableB service layer pass in the TableA.Id, A1 and check what A1 is. If good then go to the TableB repository and insert it that way?
So TableARepostiory -> TableB service layer -> TableBRepository(if found that that value != "hi").
So I am not sure what to do.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不 - 我想不出一个存储库调用另一个存储库或另一个服务的原因。他们唯一关心的应该是持久保存您的实体并从数据存储中检索实体。除了底层域之外,他们应该不了解应用程序的大多数方面。
听起来您假设它们应该是每个表的存储库,这是不正确的。每个聚合根应该有一个存储库,并且该存储库应该负责将数据存储到所有底层相关表中。存储库可以具有一些与在何处或如何保存数据相关的逻辑,但最好尽可能将其封装在公共区域中。
例如,如果您有 person 对象并需要根据性别保存到不同的表,您可以使用继承( if (person is Woman) save here... )或对象上的属性( if (person.Gender == Gender.Female) 保存在这里... ) 或规格( if (FemaleSpecification.IsSatisfiedBy(person)) 保存在这里... )。
No - i cannot think of a reason for a repository to call another repository, nor another service. Their only concern should be persisting your entities and retrieving entities from a datastore. They should be ignorant to most aspects of your application except for the underlying domain.
It sounds like you are assuming their should be a repository per table, which is incorrect. There should be a repository per aggregate root, and that repository should take care of storing data to all of the underlying, related tables. It is OK for the repository to have some logic pertaining to where or how to save the data, but it would be best for that to be encapsulated in a common area when possible.
For example if you were to have person objects and needed to save to different tables according to gender, you could do this using inheritance ( if (person is Woman) save here... ) or properties on the object ( if (person.Gender == Gender.Female) save here... ) or Specifications ( if (FemaleSpecification.IsSatisfiedBy(person)) save here... ).
保护子句(param1!=“hi”)应该位于更高层,例如应用程序服务层。
服务层应该协调两个存储库。
The guard clause (param1 != "hi") should be in a higher layer, such as an application service layer.
The service layer should coordinate the two repositories.