园里的高手,本人有个疑问,在使用EF的三层架构中,一般都是在DAL中将数据操作封装成BaseRepository<T>,然后其他dal继承这个泛型的类来实现。但是这些都是对单表操作,比如sys_userRepository,sys_depRepository这些,假如要把user表和dep表做联合查询,而且实体中也没设置两表的关系,那这个多表联合查询应该放在哪一层呢,放到BLL中吗,我现在每个Repository都有返回IQueryable的接口,所以我是在BLL中这么操作的
var q = from user in _sys_userRepository.GetAll()
join dep in _sys_depRepository.GetAll() on user.depid equals dep.depid
select new {
userid = user.account,
name = user.name,
depname = dep.depname
};
还是说这个应放在sys_userRepository增加一方法来实现,请赐教下啊!
实现不了.
如果你要联合查询.那就违反了思想.如果你要尊重思想.那你在设计业务结构的时候.就要避免这种要联合查询的情况.
"理论上"正确的做法是:你另外建一个实体类,这个用来放联合后的结果类型.然后建一个新的仓储.
其实我还是不推荐什么仓储模式.封装ef在我看来是一件毫无意义的事情.我是在想不出来为什么要封装ef.
那是不是可以建立视图,比如sys_userdepView 然后建立sys_userdepViewRepository,sys_userdepViewRepository.GetAll()来查询,或则按照你的方法建立实体类sys_userdep然后在sys_userdepRepository中增加此查询方法。
一般多表联合查询的话如何取避免,设置好实体间的关系来实现吗?
还有,不封装EF的话,你的建议EF应该怎么去用他呢,因为我们现在就是用这种模式在操作,提议看能否修正
@sammy123: 因为ef本身就是一个封装.
你仔细想想就知道ef本身就是一个仓储.
开发就用微软的demo那种方式做.最简单了.
多表联合查询其实避免不了.我之前也是通过视图来做的.
@吴瑞祥: 感谢你的答复,其实我也这么认为一直疑惑,但是公司就这么用,还有我看园子里很多人发的例子,搭的框架也都是通过将一个个实体类,封装成单个的如userRepository或则userDAL这样来用,很多人其实都是将Repository模式当做DAL层来用,看看好像就改了个名
如果就只是你举的这个例子来说,为了一个 depName 就去联合查询,当然没必要。
不过我说完解决方案,你肯定有给个一定需要联合查询的例子。
没有一劳永逸的解决方案,得看你再开发效率、运行效率、开发人员技术水平方面如何平衡。
顺便说下,只是一个 DepName, 只需要交给 CacheManager 去处理就行了。
而且通常建议新建一个 UserDto,然后使用 AutoMapper,这样你这一堆代码就不用这么麻烦了。
多看多练,每一种不同的技术解决方案,都只是表面的简单,后面都需要有一些相关如何处理复杂情况的不同方式。
高手,问下你刚才说“只是一个 DepName, 只需要交给 CacheManager 去处理就行了”,这个的话如何实现,还有假如真有多表联合查询的需求,我那样做你认可不?或则建立视图,或则为多表创建对应实体及Reposiyory
@sammy123:
// 不知道符不符合你的需求
class Program
{
static void Main(string[] args)
{
using (var db = new db())
{
// SQL:select * from user u inner join dep d on d.userid=u.id where d.id='123'
var data = db.Users.Join(db.Deps, l => l.Id, r => r.UseId, (l, r) => new
{
user = l,
dep = r
}).Where(m => m.dep.Id == "123").ToList();
}
}
}
public class db : DbContext
{
public DbSet<user> Users { get; set; }
public DbSet<dep> Deps { get; set; }
}
public class user
{
public string Id { get; set; }
}
public class dep
{
public string Id { get; set; }
public string UseId { get; set; }
}
我疑惑的是在三层结构中应该放哪来实现此代码
@sammy123: 放数据层