ASP.NET Entity Framework多表联合很头大?一文帮你解决它

场景描述

   前面说过一篇EntityFramework入门级的增删改查,可能刚刚接触EF时,都是拿一张学生表,增删改查慢慢学习EF提倡的以面向对象的思想去操作数据库(至少我在学习的时候是这样滴)。再进一步学习会发现,实际情况中我们时常会遇到下面的情况:

 主表 电影表:

电影表

从表1 电影类型表:

电影类型表

从表2 国家表:

国家表

 三表之间约束关系:

约束关系

 相信这个场景太常见了叭,两个一对多关系,主键表里面含有两个外键。我们向view展示数据的时候应该把typeId,cid转显示为用户能读懂的typeName,cname吧,这是一个极其常规的需求。

   每种情形在EF中都用四种办法来解决,帮你踩雷,相信我,总有适合你的一种!

代码干货

 从简到繁,从两表到三表 

 ------------------------------------------------------------------------------我是可爱的分割线-----------------------------------------------------------------------------------------

PS:后面会用到两个C#的语法糖,还是提一提吧,免得有的同学读不懂

1.匿名类对象

通常我们使用类的时候,一般要先定义类,并且定义字段,封装属性。

但是在我们某个时刻要使用一个类,相当于临时使用一次时,C#3.0推出的匿名类对象来解决这个问题,通常与推断类型var结合使用,因为匿名类对象没有特定的类名。

写法如下:

这样我们就实例化了一个匿名类对象student,通过var推断出匿名类对象student属于这样的一个类型。

2.自动推断成员名称

当我们有一个movie对象m和一个movieType对象mt时,我希望通过生成一个新的对象包含m,mt两个对象的属性和值,这时候我们就想到了刚说的匿名类对象,通常会这样写

代码如下:

var model =new {
                mid = m.mid,
                mname = m.mname,
                createtime = m.createtime,
                typeId = m.typeId,
                typeName = mt.typeName
            };

但是我们发现如果新生成的匿名类对象中的属性名和原来m,mt的属性名保持一致时(通常我们都会保持一致),我们的代码可以这样写:

var model = new { m.mid, m.mname, m.createtime, m.typeId, mt.typeName };

就比如:m.mid=5时,model里面就会自动生成mid属性并且值为5 

这样写非常方便、简洁!

-------------------------------------------------------------------------------我是可爱的分割线-----------------------------------------------------------------------------------------

 一、两表联合 (这里取movie和movieType联合)

  ① 方法一:Linq语句 

MoviesEntities entities = new MoviesEntities();//最开始实例化过了 后面就不再写了
var list = (from m in entities.movie
            join mt in entities.movieType on m.typeId equals mt.typeId
            select new
            {
             m.mid,m.mname,m.createtime,m.typeId,mt.typeName
            }).ToList();

 这个Linq语句没啥好说的叭! 

方法二:Linq方法

var list11 = entities.movie.Join(entities.movieType, m => m.typeId, mt => mt.typeId, (m, mt) => new
            {
                m.mid,
                m.mname,
                m.createtime,
                m.typeId,
                mt.typeName
            }).ToList();

 这里主要用的是Join()方法 我们看下这个方法的参数定义叭(*^▽^*)

我相信小白们,头一次看这个参数定义的时候一定是这样的吧!

          

不慌不慌我们细心分析一下就行。

③ 方法三:原生sql (原汁原味

但是此处要指定泛型T,所以我们要自己去写一个新类MovieDetail了。

var list2 = entities.Database.SqlQuery<MovieDetail>("select m.*,mt.typeName from movie as m inner join movieType as mt on m.typeId=mt.typeId").ToList();

④方法四:建立视图(简单粗暴

我们在SqlServer中对movie表和movietype表根据外键做一个VMovie视图

之后将这个视图添加到edmx模型中,完成之后,重新生成结局方案 两表联合的数据就有了 直接用VMovie拿来用

var list3 = entities.VMovie.ToList();

 利用视图,虽然简单、快捷,但是还是有坑滴

二、三表联合 

①方法一:Linq语句

  在两表连接后继续join即可

var list1 = (from m in entities.movie
                         join mt in entities.movieType on m.typeId equals mt.typeId
                         join c in entities.country on m.cid equals c.cid
                         select new
                         {
                             m.mid,
                             m.mname,
                             m.createtime,
                             m.typeId,
                             m.cid,
                             mt.typeName,
                             c.cname
                         }).ToList();

②方法二:Linq方法

   这里可能会有点绕,为什么第一次联合后赋一个m,因为最后我们构造新的匿名类对象时,要用到m中的各个属性,同时这个第二次Join中的a是第一次Join后返回的匿名类对象。这里确实比较绕-_-||

 var list2 = entities.movie.Join(entities.movieType, m => m.typeId, mt => mt.typeId, (m, mt) => new
            {
                mt.typeName,m
            }).Join(entities.country, a => a.m.cid, c => c.cid, (a, c) => new
            {
                a.m.mid,
                a.m.mname,
                a.m.createtime,
                a.m.cid,
                a.m.typeId,
                a.typeName,
                c.cname
            }).ToList();

③方法三:原生sql

var list3=entities.Database.SqlQuery<MovieDetail>(@"select m.*,mt.typeName,c.cname from (movie as m inner join movieType as mt on m.typeId=mt.typeId) inner join
                        country as c on m.cid = c.cid").ToList();

④方法四:建立视图

视图约束关系:

var list3 = entities.VMovie.ToList();

----------------------------------------------------------------------------我是可爱的分割线--------------------------------------------------------------------------------------------

 EF中使用视图的踩坑小记

坑一: 

       警告 6002: 表/视图 未定义主键

这个警告很烦人,每次生成的时候后,都会弹这个警告,因为EF没有检测到表/视图中的主键,但是我们可能会说,我在SqlServer建立的视图压根就没有特定的主键啊!

解决方案:

使用人家EF,你就要迎合人家的规则,在视图创建的时候,加一列值不重复且为 not null的列就行了,EF就检测到有主键了,就不会再警告你啦 一般加一列Guid或者是RowNumber

 select ISNULL(NEWID(), '5757E7EF-2F19-4408-B413-8F1B33B9895F') AS id,col1,col2,col3
 from xxxx

这时候,你再回到edmx中从数据库更新模型后会发现,警告6002依旧存在!!!

没关系,关闭VisualStudio,重新打开,警告就消失了

好了这个坑 完美解决

坑二: 

       操作VMovie的时候使用Find()方法

前几天再给几个同学改代码的时候,发现他们习惯性的使用Find()查对象,最后在VMovie上使用Find()传个ID就报错了。

因为Find()是根据主键查对象的,VMovie是个视图,本身就没有自己特定的主键,为了解决坑一,我们加了一个GUID主键,所以当然不能像单表查询那样,传一个主键来解决问题了。

    解决方案:

   使用FirstOrDefault或者Where

坑三:

     直接对VMovie进行增删改

因为VMovie的本质是个视图,数据库中的一张虚拟表,我们把视图添加到edmx中只是为了查询数据方便,不能直接进行增删改

       解决方案:

直接对主表movie进行增删改,视图会进行自动更新

    我相信看完这篇博客之后,使用EF处理简单的多表联合就不是什么难事了吧,当初我在学习的时候,也是遇到各种各样的问题,去网上也搜了各种方法,但是都是就事论事,说的不全面,有的还根本行不通,但是现在各种方法都有了,坑都踩了,大胆向前冲吧 !

 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
.NET Entity Framework(EF)是微软提供的一种对象关系映射(ORM)框架,用于简化和加速开发者与数据库之间的交互。它允许开发者使用面向对象的方式来操作数据库,而无需直接编写SQL语句。以下是一些与.NET Entity Framework相关的基本知识: 1. 什么是.NET Entity Framework? .NET Entity Framework是一个开源的ORM框架,它允许开发者通过定义实体类和关系来操作数据库。它提供了一个对象关系映射器,可以将数据库映射到.NET实体类,使开发者可以使用面向对象的思维来操作数据库。 2. Entity Framework有哪些核心组件? Entity Framework包括以下核心组件: - DbContext:示数据库上下,用于管理实体对象与数据库之间的交互。 - DbSet:示数据库中的实体集合,用于查询、插入、更新和删除实体。 - Entity示映射到数据库的实体类。 - LINQ to Entities:用于编写查询语句,将LINQ查询转换为SQL语句并执行。 3. 如何使用Entity Framework进行数据库操作? 使用Entity Framework进行数据库操作通常包括以下步骤: - 定义实体类:创建示数据库的实体类。 - 创建DbContext:继承自DbContext的类,示数据库上下。 - 配置映射关系:使用Fluent API或属性注解来配置实体类与数据库之间的映射关系。 - 执行数据库操作:使用DbContext的方法(如SaveChanges、Add、Remove等)来执行对数据库的增删改查操作。 4. Entity Framework支持哪些数据库提供程序? Entity Framework支持多种数据库提供程序,包括SQL Server、MySQL、Oracle、SQLite等。可以根据需要选择合适的数据库提供程序。 5. 如何进行查询操作? 使用Entity Framework可以使用LINQ查询语法或方法链式调用来进行查询操作。通过DbContext的DbSet属性获取实体集合,然后可以使用LINQ查询来过滤、排序和投影数据。 6. 如何进行数据迁移? 数据迁移是Entity Framework提供的一种机制,用于管理数据库结构的变更。可以使用命令行工具或Package Manager Console来创建和应用数据迁移脚本,以保持数据库结构与代码模型的一致性。 .NET Entity Framework是一个功能强大且广泛使用的ORM框架,它简化了与数据库的交互,提高了开发效率。建议深入学习和掌握Entity Framework的各种特性和用法,以便在实际项目中充分发挥其优势。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值