首页 新闻 会员 周边

.net mvc 三层架构中多表联合查询 如何实现

1
悬赏园豆:20 [已解决问题] 解决于 2019-04-06 07:26

园里的高手,本人有个疑问,在使用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增加一方法来实现,请赐教下啊!

sammy123的主页 sammy123 | 初学一级 | 园豆:174
提问于:2019-04-04 12:07
< >
分享
最佳答案
0

实现不了.
如果你要联合查询.那就违反了思想.如果你要尊重思想.那你在设计业务结构的时候.就要避免这种要联合查询的情况.
"理论上"正确的做法是:你另外建一个实体类,这个用来放联合后的结果类型.然后建一个新的仓储.
其实我还是不推荐什么仓储模式.封装ef在我看来是一件毫无意义的事情.我是在想不出来为什么要封装ef.

收获园豆:15
吴瑞祥 | 高人七级 |园豆:29449 | 2019-04-04 12:25

那是不是可以建立视图,比如sys_userdepView 然后建立sys_userdepViewRepository,sys_userdepViewRepository.GetAll()来查询,或则按照你的方法建立实体类sys_userdep然后在sys_userdepRepository中增加此查询方法。
一般多表联合查询的话如何取避免,设置好实体间的关系来实现吗?
还有,不封装EF的话,你的建议EF应该怎么去用他呢,因为我们现在就是用这种模式在操作,提议看能否修正

sammy123 | 园豆:174 (初学一级) | 2019-04-04 12:38

@sammy123: 因为ef本身就是一个封装.
你仔细想想就知道ef本身就是一个仓储.
开发就用微软的demo那种方式做.最简单了.
多表联合查询其实避免不了.我之前也是通过视图来做的.

吴瑞祥 | 园豆:29449 (高人七级) | 2019-04-04 12:41

@吴瑞祥: 感谢你的答复,其实我也这么认为一直疑惑,但是公司就这么用,还有我看园子里很多人发的例子,搭的框架也都是通过将一个个实体类,封装成单个的如userRepository或则userDAL这样来用,很多人其实都是将Repository模式当做DAL层来用,看看好像就改了个名

sammy123 | 园豆:174 (初学一级) | 2019-04-04 12:49
其他回答(2)
0

如果就只是你举的这个例子来说,为了一个 depName 就去联合查询,当然没必要。
不过我说完解决方案,你肯定有给个一定需要联合查询的例子。
没有一劳永逸的解决方案,得看你再开发效率、运行效率、开发人员技术水平方面如何平衡。

顺便说下,只是一个 DepName, 只需要交给 CacheManager 去处理就行了。
而且通常建议新建一个 UserDto,然后使用 AutoMapper,这样你这一堆代码就不用这么麻烦了。

多看多练,每一种不同的技术解决方案,都只是表面的简单,后面都需要有一些相关如何处理复杂情况的不同方式。

收获园豆:5
爱编程的大叔 | 园豆:30839 (高人七级) | 2019-04-04 12:53

高手,问下你刚才说“只是一个 DepName, 只需要交给 CacheManager 去处理就行了”,这个的话如何实现,还有假如真有多表联合查询的需求,我那样做你认可不?或则建立视图,或则为多表创建对应实体及Reposiyory

支持(0) 反对(0) sammy123 | 园豆:174 (初学一级) | 2019-04-04 19:04

@sammy123:

  1. 通常 Department 总是不会太多,反复查询没有必要还浪费资源和时间。CacheManager 你可以简单理解就是内存中保存一个 Departments 集合,需要Name 的时候, 你拿Id取查出来。
    具体实现你就先不用管需要多么优雅,自己试试看,也不会算太难。
  2. 你说的多种方法都是可以的,不需要为了只是追求一种最好的方法而把自己搞得不懂编程了。
    各种方法我都用过。
支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2019-04-04 23:35
0

// 不知道符不符合你的需求

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; }
}
Vin° | 园豆:164 (初学一级) | 2019-04-04 16:57

我疑惑的是在三层结构中应该放哪来实现此代码

支持(0) 反对(0) sammy123 | 园豆:174 (初学一级) | 2019-04-04 18:56

@sammy123: 放数据层

支持(0) 反对(0) Vin° | 园豆:164 (初学一级) | 2019-12-08 21:41
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册