Entity Framework with MySQL 学习笔记一(查询)

参考 : http://msdn.microsoft.com/en-us/data/jj574232.aspx

EF 查询基本上有3中

默认是 Lazy Loading

特色是只有在需要数据的时候EF才会像数据库请求,它不会使用任何inner join

比如我们有一个产品,有很多颜色,(1对多)

那么我们想把每个产品和颜色统统选出来

using (EFDB db = new EFDB())
{
    var prods = db.prods.ToList(); //像数据库请求prods, 但是不会包括colors
    foreach (var prod in prods)
    {
        var color = prod.colors; //每一次都像数据库请求颜色
    }
}

首先必须用 ToList(),不然之后的 prod.colors是会报错的。

如果prods有很多,它会发出很多次请求,这对性能是有影响的!

Opened connection at 2014/9/27 23:26:47 +08:00
SELECT
`Extent1`.`id`,
`Extent1`.`color`,
`Extent1`.`prod_id`
FROM `prod_color` AS `Extent1`
 WHERE `Extent1`.`prod_id` = @EntityKeyValue1
-- EntityKeyValue1: ‘2‘ (Type = Int32, IsNullable = false)
-- Executing at 2014/9/27 23:26:47 +08:00
-- Completed in 12 ms with result: EFMySqlDataReader

Closed connection at 2014/9/27 23:26:47 +08:00
Opened connection at 2014/9/27 23:26:48 +08:00
SELECT
`Extent1`.`id`,
`Extent1`.`color`,
`Extent1`.`prod_id`
FROM `prod_color` AS `Extent1`
 WHERE `Extent1`.`prod_id` = @EntityKeyValue1
-- EntityKeyValue1: ‘3‘ (Type = Int32, IsNullable = false)
-- Executing at 2014/9/27 23:26:48 +08:00
-- Completed in 12 ms with result: EFMySqlDataReader

Closed connection at 2014/9/27 23:26:48 +08:00
Opened connection at 2014/9/27 23:26:49 +08:00
SELECT
`Extent1`.`id`,
`Extent1`.`color`,
`Extent1`.`prod_id`
FROM `prod_color` AS `Extent1`
 WHERE `Extent1`.`prod_id` = @EntityKeyValue1
-- EntityKeyValue1: ‘4‘ (Type = Int32, IsNullable = false)
-- Executing at 2014/9/27 23:26:49 +08:00
-- Completed in 11 ms with result: EFMySqlDataReader

Closed connection at 2014/9/27 23:26:49 +08:00

所以通常我们不是很喜欢用lazy loading

第2种呢是 Eagerly Loading

它主要是使用了 Include 方法来调用 inner join ,使查询次数减少 

using (EFDB db = new EFDB())
{
    db.Configuration.LazyLoadingEnabled = false;
    var prods = db.prods.Include(p => p.colors).ToList(); //像数据库请求prods和colors
    //var prods = db.prods.Include(p => p.colors.Select(c => c.sizes)).ToList();  如果还有sizes
    foreach (var prod in prods)
    {
        var color = prod.colors; //不需要再请求了
    }
}

Opened connection at 2014/9/27 23:41:23 +08:00
SELECT
`Project1`.`id`,
`Project1`.`code`,
`Project1`.`name`,
`Project1`.`C1`,
`Project1`.`id1`,
`Project1`.`color`,
`Project1`.`prod_id`
FROM (SELECT
`Extent1`.`id`,
`Extent1`.`code`,
`Extent1`.`name`,
`Extent2`.`id` AS `id1`,
`Extent2`.`color`,
`Extent2`.`prod_id`,
CASE WHEN (`Extent2`.`id` IS  NULL) THEN (NULL)  ELSE (1) END AS `C1`
FROM `prod` AS `Extent1` LEFT OUTER JOIN `prod_color` AS `Extent2` ON `Extent1`.`id` = `Extent2`.`prod_id`) AS `Project1`
 ORDER BY
`Project1`.`id` ASC,
`Project1`.`C1` ASC
-- Executing at 2014/9/27 23:41:24 +08:00
-- Completed in 14 ms with result: EFMySqlDataReader

Closed connection at 2014/9/27 23:41:24 +08:00

语句很吓人,子查询都出来了。我想对数据库人员来说,这查询决定是不合格的...

第3种是 Explicitly Loading

这个和 lazy loading 差不多,只是可以手动去控制

using (EFDB db = new EFDB())
{
    db.Configuration.LazyLoadingEnabled = false;
    //var prods = db.prods.Include(p => p.colors).ToList(); //像数据库请求prods和colors
    //var prods = db.prods.Include(p => p.colors.Select(c => c.sizes)).ToList();  如果还有sizes
    var prods = db.prods.ToList();
    foreach (var prod in prods)
    {
        var color = prod.colors; //null
        db.Entry(prod).Collection(p => p.colors).Load(); //像数据库发送请求
        //db.Entry(prod).Collection(p => p.colors).Query().Where(c => c.color == "red").Load(); //加过滤的话
        color = prod.colors; //有了
    }
}

Opened connection at 2014/9/27 23:47:13 +08:00
SELECT
`Extent1`.`id`,
`Extent1`.`code`,
`Extent1`.`name`
FROM `prod` AS `Extent1`
-- Executing at 2014/9/27 23:47:13 +08:00
-- Completed in 13 ms with result: EFMySqlDataReader

Closed connection at 2014/9/27 23:47:13 +08:00
Opened connection at 2014/9/27 23:47:15 +08:00
SELECT
`Extent1`.`id`,
`Extent1`.`color`,
`Extent1`.`prod_id`
FROM `prod_color` AS `Extent1`
 WHERE `Extent1`.`prod_id` = @EntityKeyValue1
-- EntityKeyValue1: ‘1‘ (Type = Int32, IsNullable = false)
-- Executing at 2014/9/27 23:47:15 +08:00
-- Completed in 13 ms with result: EFMySqlDataReader

Closed connection at 2014/9/27 23:47:15 +08:00
Opened connection at 2014/9/27 23:47:17 +08:00
SELECT
`Extent1`.`id`,
`Extent1`.`color`,
`Extent1`.`prod_id`
FROM `prod_color` AS `Extent1`
 WHERE `Extent1`.`prod_id` = @EntityKeyValue1
-- EntityKeyValue1: ‘2‘ (Type = Int32, IsNullable = false)
-- Executing at 2014/9/27 23:47:17 +08:00
-- Completed in 13 ms with result: EFMySqlDataReader

Closed connection at 2014/9/27 23:47:17 +08:00
Opened connection at 2014/9/27 23:47:17 +08:00
SELECT
`Extent1`.`id`,
`Extent1`.`color`,
`Extent1`.`prod_id`
FROM `prod_color` AS `Extent1`
 WHERE `Extent1`.`prod_id` = @EntityKeyValue1
-- EntityKeyValue1: ‘3‘ (Type = Int32, IsNullable = false)
-- Executing at 2014/9/27 23:47:17 +08:00
-- Completed in 13 ms with result: EFMySqlDataReader

Closed connection at 2014/9/27 23:47:17 +08:00
Opened connection at 2014/9/27 23:47:17 +08:00
SELECT
`Extent1`.`id`,
`Extent1`.`color`,
`Extent1`.`prod_id`
FROM `prod_color` AS `Extent1`
 WHERE `Extent1`.`prod_id` = @EntityKeyValue1
-- EntityKeyValue1: ‘4‘ (Type = Int32, IsNullable = false)
-- Executing at 2014/9/27 23:47:17 +08:00
-- Completed in 14 ms with result: EFMySqlDataReader

Closed connection at 2014/9/27 23:47:17 +08:00

也是用了很多的查询...

目前我还没有找到比较可以接受的查询方式。至少我觉得对性能有点要求的人应该不会使用上面任何一种方法吧..

继续专研...待续

时间: 2024-08-08 01:40:44

Entity Framework with MySQL 学习笔记一(查询)的相关文章

Entity Framework with MySQL 学习笔记一(安装)

声明 :  数据库是Mysql,本人的程度只到会写sql语句(不会储蓄过程), c# 会基本的ADO.NET数据库访问,LINQ基础. 这篇只做个人学习|温习作用. 新手可以参考,也请高手指正错误, 感恩. Entity Framework (缩写EF) 是微软的一个框架.作用是处理面向对象与关系数据库的映射问题. 以往我们都是ADO.NET来访问数据库,connection.open() -> sql command ->  executenonquery | dataReader ->

Entity Framework with MySQL 学习笔记一(查看EF和SQL记入)

做数据库的一向来都会很注意请求的次数还有语句.这关系到很多性能的问题. 因此在使用EF的时候如果不了解原理很可能会搞出很糟糕的请求. 所以呢,在还没有搞懂EF前最基本的是你得"看得见",EF为我们生成了什么样的 SQL语句,和访问了多少次SQL 其实有很多很好的工具可以实现这些东西,但是我懒的去找来试,所以呢找了一个简单又勉强可以用用的. 这个是微软本身的日志 参考 : http://msdn.microsoft.com/en-us/data/jj556606 -Logging Dat

Entity Framework with MySQL 学习笔记一(乐观并发)

在做项目时,通常我们对乐观并发有几种处理模式 1. 告诉用户此数据已被其他人捷足先登,更改了.你就算新一下重来吧. 2.直接把数据覆盖上去,我最大. 3.用被人的数据. 这里给出 code first 的做法 [Table("product")] [JsonObject(IsReference = true)] public class Product { [Key] public int id { get; set; } public string code { get; set;

Entity Framework with MySQL 学习笔记一(继承)

基本上sql中要表示继承关系有3中方式. 分别是,1表继承(TPH),2表继承(TPC),3表继承(TPT) 1表 : Person id type name classroom office 1 student  keat       1B null 2      teacher  xinyao    null  Lv2-T2 好处是不用 inner join 快,坏处是null 很多,浪费空间, column很长不好看. 2表: 这个很瞎不要学 .. , 大概就是没有父表,字表很多,但是每个

Entity Framework with MySQL 学习笔记一(常用小总结)

1-1 设置 //DataAnnotation 1-1 | 1-0 table //SQLtable : member , columns : memberId, name //SQL basic logic : 1个table的PK, 是另一个table的PK and FK , 这就是1-1和1-0的关系 [Table("member")] public class Member { [Key] public Int32 memberId { get; set; } public s

Entity Framework with MySQL 学习笔记一(关系)

这一篇说说 EF Fluent API 和 DataAnnotations 参考 : http://msdn.microsoft.com/en-us/data/jj591617.aspx http://msdn.microsoft.com/en-us/data/jj591620.aspx

Entity Framework with MySQL 学习笔记一(insert,update,delete)

先说说 insert 吧. 当EF执行insert时,如果我们传入的对象是有关联(1对多等)的话,它会执行多个语句 insert到多个表, 并且再select出来填充我们的属性(因为有些column默认值是sql设定的,比如id等,我们insert后要有最新的数据丫). using (EFDB db = new EFDB()) { db.prods.Add(new Prod { code = "mk100", name = "name", detail = new

Entity Framework with MySQL 学习笔记一(复杂类型 Complex Types)

有时候我们希望在sql一个表里面的column, 一部分被分化成另一个class 典型的例子是 Address 直接看代码: [Table("member")] public class Member { [Key] public Int32 memberId { get; set; } public string name { get; set; } public virtual Address address { get; set; } } /* 不能公开 - public DbS

MySQL学习笔记-子查询和连接

MySQL学习笔记-子查询和连接 使客户端进入gbk编码方式显示: mysql> SET NAMES gbk; 1.子查询 子查询的定义: 子查询(Subquery)是指出现在其他SQL语句内的SELECT子句. 例如:  SELECT * FROM t1 WHERE col1 = (SELECT col2 FROM t2); 其中SELECT * FROM t1 称为Outer Query / Outer Statement (外部查询) SELECT col2 FROM t2 , 被称为Su