在阅读ASP.NET MVC 3.0项目中的Repository Design模式后,我遇到了一个让我困惑的问题,并开始质疑模式的好处。也许有人可以帮我澄清这一点。存储库模式:好还是坏?
我有以下3个表:
- - 用户(
parent
) - - UserLead(
child of User
) - - UserLeadNotes(
child of UserLead
)
粗略地说,表和它们之间的关系是这样设计的:
- 用户[ID]
- UserLead[ID,用户ID(外键)
- UserLeadNotes[Id,UserLeadId(外键)]
我有一个BaseRepository,其中包含基本的CRUD方法。 (IEnumerable<TEntity> Get(), TEntity GetByID(), Insert(), Delete(), etc…)
随着到位,我也有一个Service Layer
如果在需要的时候并调用适当的存储库。
简而言之,应用程序显示一个UserLead并允许用户添加/删除该UserLead的注释(在UserLeadNotes表中存储/删除)。添加/删除笔记通过Ajax调用完成。注释的删除沿着我希望删除的注释的“id”
传递。
现在...之前,我确实删除的笔记,我需要确保的音符真正属于自己的登录用户当前(User.Identity.Name aka UserId
)
考虑我的方法deleteUserNote(int noteId)
只接收一个“noteId”
参数和考虑我UserLeadNotes表不对UserId
外键,我需要做的,就是增加一个
。包括(“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);
问题:
按照上面的方法,这将迫使我为我的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个字段)。
除非我没有正确使用存储库模式,或者这可能是一个实体框架问题,否则我想知道任何人的想法!
请记住,我知道有一个存储库模式的好处,但好奇,如果这是人们有或没有的某种问题。如果是这样,他们是否决定放弃模式,并使用Linq语句直接使用它们的上下文。
两个邪恶中最小的是什么?
我在一些项目上使用了该模式,但放弃了它,直接转向上下文。如果你继续使用模式,你应该阅读** Aggregate Roots **。你不需要为每个表/实体回购,只是你的核心部分。我通常为复杂的业务逻辑/关系保留完整的DDD。 http://devlicio.us/blogs/casey/archive/2009/02/16/ddd-aggregates-and-aggregate-roots.aspx – Ryan
我现在更明白我的UserLead和UserLeadNotes表将被视为一个聚合。所以我的UserLead表将被视为聚合根。这意味着我应该只有一个针对该聚合根表的存储库,并从该根目录导航到我的子项。考虑到这一点,如何使我的单个UserLead存储库允许我导航到我的孩子并获得FirstOrDefault()子对象而不加载父代的附加字段?也许你是对的;我应该删除存储库模式,并直接从我的服务层调用/使用我的上下文 – Vlince