0
点赞
收藏
分享

微信扫一扫

EF中逆变和协变

EF中的增删改查:

实现步骤:

1.声明一个EF的上下文。

bjhksjEntities dbContext = new bjhksjEntities();

2.声明一个实体。

HKSJ_USERS user = new HKSJ_USERS();
user.LoginName = "ssss";
user.Mail = "ssss";
user.PassWord = "ssss";
user.Plane = "ssss";
user.UserName = "ssss";
user.cardNo = "ssss";
user.phone = "ssss";

3.告诉EF对实体做什么操作。

插入:
dbContext.HKSJ_USERS.Add(user);

修改和删除的时候必须指定ID:
HKSJ_USERS user = new HKSJ_USERS();
user.LoginName = "ssss111--------"
user.Mail = "ssss";
user.PassWord = "ssss";
user.Plane = "ssss";
user.UserName = "ssss";
user.cardNo = "ssss";
user.phone = "ssss";
user.ID = 8;

进行修改操作:
dbContext.Entry<HKSJ_USERS>(user).State = System.Data.EntityState.Modified;

附加到上下文中进行管理(跟踪才能用SQL Server Profiler工具):
dbContext.HKSJ_USERS.Attach(user);

修改单个属性(两种写法):
dbContext.Entry<HKSJ_USERS>(user).Property<string>(u => u.LoginName).IsModified = true;
dbContext.Entry<HKSJ_USERS>(user).Property("LoginName").IsModified = true;

4.让上下文把变化的实体保存到数据库中。(也是执行Sql脚本的地方)

dbContext.SaveChanges();

遇到这种错误:

EF中逆变和协变_泛型

实体的属性(非空、不全、超过长度)

EF中逆变和协变_泛型_02

上面的错误是没有主键。

EF中逆变和协变_父类_03

数据已经不存在了又做了一个删除操作。或者ID没有赋值

 

聚簇索引和非聚簇索引的区别:
聚簇索引:索引的顺序和数据存储的顺序一致。一一对应(Guid一般不设置成聚簇索引 -----Guid无序)

非聚簇索引:(树状结构)要不通过聚簇索引找到数据库表的数据    或者自己找到数据库表的顺序。

 

ModelFirst生成数据库时注意:

EF中逆变和协变_数据库_04

EF在运行时改链接字符串:

dbContext.Database.Connection.ConnectionString=“”;

 

模型和数据库中的列进行同步:

空白处右击:

EF中逆变和协变_父类_05

然后保存,model层就会自动生成添加列的相对属性。

或者转换所有的T4模板:

EF中逆变和协变_泛型_06

 

模型中添加的字段同步到数据库:

右键根据模型生成数据库:

EF中逆变和协变_数据库_07

下一步会生成一个数据库脚本.(执行)

有数据的话手动添加对应的列

 

Linq表达式和Sql语句的区别:

select *  --1
from 表名 as u --2
where u.列名 like '%s%' --3

--执行的顺序 2,3,1

--linq
from 表名
where u.列名 like '%s%'
select *

 

EF查询:

这两个意思一样:
var temp = from u in dbContext.HKSJ_USERS
select u;
foreach (var u in dbContext.HKSJ_USERS)
{

}
Linq表达式的返回类型是IQueryable<T> 继承IEnumerable<T>

out  输出参数(干涉返回值) --子类的泛型集合传给父类的泛型集合  协变   外面使用的是父类的泛型集合  编译阶段补充完整代码,本质还是内部进行转换,只不过是编译不对其报错。
in 输入参数(干涉传入的参数) --父类的泛型集合传给子类的泛型集合 逆变 (使用的时候安全 不是赋值的时候安全)

这样是不对的:
List<int> listInt = new List<int>() { 1, 2, 3 };
List<object> listObj = listInt;

错误如下:

 

EF中逆变和协变_父类_08

IQueryable<HKSJ_USERS> temp = from u in dbContext.HKSJ_USERS
where u.ID > 4
select u;

//把子类泛型集合交给父类的泛型集合。协变。
IQueryable<object> parent = temp;

 

2、逆变,还是为了安全。把父类的泛型给子类的泛型对象。
Action<object> b = (target) =>
{
Console.WriteLine(target.GetType().Name);
};
Action<HKSJ_USERS> d = b;
d(new HKSJ_USERS());

赋值的时候是把父类的方法传给子类 使用的时候还是把子类的方法传给父类

 

EF中逆变和协变_泛型_09

 

Linq to EF:查询实在数据库端进行过滤

内存里面过滤:把数据库中的所有数据都查询到程序里面来之后,在进行过滤。

 

List集合(Array、Dictionary...)跟IQueryable接口集合的不同点。

这种写法把所有的数据加载到内存中去:(Linq to Object) 条件在内存中进行过滤   数据库中查询所有。(.ToLis立即加载到内存中)本地集合

var demoList = from u in dbContext.HKSJ_USERS.ToList()
where u.ID > 4
select u;
foreach (var hksjUsers in demoList)
{

}

 对此句代码进行分析:

IQueryable<HKSJ_USERS> temp = from u in dbContext.HKSJ_USERS
where u.ID > 4
select u;

 初始化了一下IQueryable接口里面的三个参数:(离线集合)

1.Linq 表达式转换成Expression类型

2.给 Type  ElementType赋值

3.给IQueryProvider  Provider赋值 

当用到IQueryable接口集合数据的时候,provider解析 Expression 然后获取相应的数据,进行遍历执行

 

内部的代码:

EF中逆变和协变_数据库_10

Linq的一个工具:(LINQPad)

EF中逆变和协变_数据库_11

 

最后来一张图:本地集合List(分配四个内存):

EF中逆变和协变_数据库_12



举报

相关推荐

0 条评论