【发布时间】:2023-03-19 06:55:01
【问题描述】:
在阅读了 ASP.NET MVC 3.0 项目中存储库设计模式的好处(和使用)之后,我遇到了一个让我感到困惑并开始质疑该模式的好处的问题。也许有人可以帮助我澄清这一点。
我有以下 3 个表:
- -用户 (
parent) - -UserLead (
child of User) - -UserLeadNotes (
child of UserLead)
大致上,表格及其关系设计如下:
- 用户 [Id]
- UserLead [Id, UserId(外键)]
- UserLeadNotes [Id, UserLeadId(外键)]
我有一个包含基本 CRUD 方法的 BaseRepository。
(IEnumerable<TEntity> Get(), TEntity GetByID(), Insert(), Delete(), etc…)
有了这个,我还有一个Service Layer,它会在需要时调用适当的存储库。
简而言之,应用程序显示一个 UserLead 并允许用户向该 UserLead 添加/删除注释(在 UserLeadNotes 表中存储/删除)。添加/删除注释是通过 Ajax 调用完成的。 删除一条笔记会传递我希望删除的笔记的“id”。
现在……在我真正删除笔记之前,我需要确保该笔记真正属于当前登录的用户(User.Identity.Name aka UserId)
考虑到我的方法deleteUserNote(int noteId) 只接收“noteId” 参数AND 考虑到我的UserLeadNotes TABLE 没有 在UserId 上有外键,我需要什么要做的是添加一个
.Include(“UserLead”)
在我的_userLeadNoteRepository 里面有类似的东西:
UserLeadNote userLeadNote = _userLeadNoteRepository
.AllIncluding(p => p.UserLead)
.FirstOrDefault(p => p.UserLeadNoteID.Equals(noteId)
&& p.UserLead.UserID.Equals(User.Identity.Name));
然后我会删除我刚刚找到的 UserLeadNote 对象:
_userLeadNoteRepository.Delete(userLeadNote);
问题:
按照上述方法,这将迫使我 a) 为我的 UserLeadNotes 和 b) 创建一个存储库,因为 .Include() 找到的 userLeadNote 对象将具有一个名为 UserLead 的属性,其中包含所有定义的字段在 UserLead 表中。
如果我的 UserLead 表恰好有 14 个字段,其中 10 个字段是 ntext,这意味着我会无缘无故地加载/保存太多信息!
如果我要使用,而不是 Lambda 表达式,绕过存储库并直接使用我的上下文的 Linq 语句:
using(MyContext db = new MyContext ())
{
var query =
from uln in db.UserLeadNote
join ul in db.UserLead on uln.UserLeadID equals ul.UserLeadID
where uln.UserLeadNoteID == userLeadNoteID
&& ul.UserID == User.Identity.Name
select uln;
var userLeadNote = query.FirstOrDefault();
db.UserLeadNote.Remove(userLeadNote);
db.SaveChanges();
}
这种方法会不会更有效,因为它不会从 UserLead 表中带回那些不必要的字段? (例如那 10 个 ntext 字段)。
除非我没有正确使用存储库模式,或者这可能是实体框架问题,否则我想知道任何人的想法!
请记住,我知道使用存储库模式的好处,但很好奇这是否是人们遇到的某种问题。如果是这样,他们是否决定放弃 Pattern 并使用 Linq 语句直接使用他们的上下文。
两害相权取其轻?
【问题讨论】:
-
我在几个项目中使用了该模式,但为了直接进入上下文而放弃了它。如果您继续使用该模式,您应该阅读Aggregate Roots。您不希望每个表/实体都有一个 repo,只需要您的核心。我通常为复杂的业务逻辑/关系保留完整的 DDD。 devlicio.us/blogs/casey/archive/2009/02/16/…
-
我现在更好地理解了我的 UserLead 和 UserLeadNotes 表将被视为一个聚合。所以我的 UserLead 表将被视为聚合根。这意味着我应该只有一个用于该聚合根表的存储库,并从该根导航到我的孩子。考虑到这一点,让我的单个 UserLead 存储库如何允许我导航到我的孩子并获得 FirstOrDefault() 子对象而不加载父级的附加字段?也许你是对的;我应该放弃存储库模式并直接从我的服务层调用/使用我的上下文
标签: asp.net-mvc repository-pattern