23---WPF数据库ORM框架
一、仓库--存放货物---数据库--存放数据--关系型数据/非关系型数据库
1.关系型数据:保存数据+保存关系--SqlServer,MySql,Oracle
2.非关系型数据:保存数据---Redis,Mongo,Memecahe
二、关系型数据和非关系型数据的区别:
1.关系型数据 持久化保存---保存在硬盘上--数据库中的数据操作会很慢!大数据量底层本保存
2.非关系型数据:持久化成本高--保存在内存--不能持久化; 就是快;数据量大--太大还搞不了,成本高--价格贵
三、数据是为了程序--各种开发的系统服务的---程序如何链接数据库来操作
1.Ado.NET---原生的ado.net 最纯粹的链接数据库的帮助类库---性能快;操作不方便;
2.ORM: object-relational-mapping对象关系映射--对象--类--可以通过对类的操作完成对于数据库的操作---对类的操作---面向对象的编程思想;
四、ORM框架
1.做到了通过面向对象的思想去操作数据库
2.底层本质还是ado.net --- 基于ado.net 的上层封装--用起来很爽
3.开发效率高--不用理会Sql语句
4.底层当然还是Sql语句---中间必然有一个实体对象到Sql语句的生成过程--通用的,通过程序来生成SQL语句---Sql语句不是那么简洁--Sql语句相对比较僵化---读取类中的元素,生成Sql语句---必然会大量的反射---反射损耗性能
5.ORM框架--性能不好~~
五、常见的ORM框架:
1.EFCore---功能强大的,优化了之前的一些问题--性能不低~~
2.SqlSugar---牛逼--性能也比价高--功能也很强大~~
3.FreeSql
4.Dapper ---高性能
六、EfCore 开始
1.映射-- (.NET Framework下 EF6 EF5) ---DbFirst---CodeFirst
2.EfCore--DbFirst----DB--数据库---数据库先行--数据库先设计,通过数据库生成代码;
DbFirst:
Nuget引入:
Microsoft.EntityFrameworkCore ---操作数据库的各种api
EntityFrameworkCore.SqlServer ---匹配不同的数据库
EntityFrameworkCore.Tools ---工具--一些帮助类库--迁移
EntityFrameworkCore.SqlServer.Design
注上述报错使用:Scaffold-DbContext "Server=.;Database=WPFCustomerDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
WPFCustomerDBContext context = new WPFCustomerDBContext();
//增加
context.Commodities.Add(new Commodity() { ProductId=234,CategoryId=1,Url="Urltest",Price=456789,Title="CommodityTitle"});
context.SaveChanges();
//查询
IQueryable<Commodity> commodities = context.Commodities.Where(c => c.ProductId == 234);
foreach (var commodity in commodities)
{
Console.WriteLine("rn************************");
Console.WriteLine($"Id:{commodity.Id}");
Console.WriteLine($"ProductId:{commodity.ProductId}");
Console.WriteLine($"CategoryId:{commodity.CategoryId}");
Console.WriteLine($"Title:{commodity.Title}");
Console.WriteLine($"Url:{commodity.Url}");
}
//修改
Commodity commodity1=context.Commodities.OrderByDescending(c => c.Id).FirstOrDefault();
commodity1.Title = commodity1.Title + DateTime.Now.ToString("f");
context.SaveChanges();
//删除
context.Remove(commodity1);
context.SaveChanges();
解决映射表和数据库的表名和字段不一致的情况---特性映射
代码先行的编码方式
注:"Server=.;Database=WPFCustomerDB_Migrations;User ID=sa;Password=xxxxxx;TrustServerCertificate=True;"
报错:Microsoft.Data.SqlClient.SqlException:“A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - 证书链是由不受信任的颁发机构颁发的。)”
解决:这个错误意味着连接已建立,但在登录过程中出现了错误。错误消息指出,SSL证书链是由不受信任的颁发者颁发的,这意味着你的数据库服务器证书是自签名的或由不受信任的CA颁发的。为确保安全,SSL证书应由受信任的证书颁发机构颁发。你可以尝试安装证书并将其添加到可信证书颁发机构列表中,或者更改连接字符串中的TrustServerCertificate为True(不建议在生产环境中使用),以便忽略证书问题。
数据库迁移
1.生成迁移文件
MPC命令:
add-migration migrationName ---添加迁移文件
remove-migration ---删除迁移文件
update-database ---通过迁移文件生成数据库
update-database migrationName ---指定某一个迁移文件生成数据库
基于WPFCustomerDbContext 对象的其他查询
#region 其他查询
using (WPFCustomerDbContext dbContext = new WPFCustomerDbContext())
{
{
var ids = new int[] { 54, 55, 56, 57, 58, 59, 60, 61, 63 };
var list = dbContext.SysUsers.Where(u => 1 == 1 && !ids.Contains(u.Id));//in查询
foreach (var user in list)
{
Console.WriteLine(user.Name);
}
}
{
var list = from u in dbContext.SysUsers
where new int[] { 54, 55, 56, 57, 58, 59, 60, 61, 63 }.Contains(u.Id)
select u;
foreach (var user in list)
{
Console.WriteLine(user.Name);
}
}
{
var list = dbContext.SysUsers.Where(u => new int[] { 54, 55, 56, 57, 58, 59, 60, 61, 63 }.Contains(u.Id))
.OrderBy(u => u.Id) //排序--升序
.OrderByDescending(c => c.Name)
.Select(u => new //投影
{
u.Name,
Pwd = u.Password
}).Skip(3).Take(5); //跳过三条 再获取5条
foreach (var user in list)
{
Console.WriteLine(user.Name);
}
}
{
var list = dbContext.SysUsers.Where(u => u.Name.StartsWith("Richard") && u.Name.EndsWith("Richard"))
.Where(u => u.Name.EndsWith("Richard"))
.Where(u => u.Name.Contains("Richard"))
.Where(u => u.Name.Length < 10)
.OrderBy(u => u.Id);
foreach (var user in list)
{
Console.WriteLine(user.Name);
}
}
{
var list = from c in dbContext.Companies
join u in dbContext.SysUsers on c.Id equals u.CompanyId
where new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14, 17 }.Contains(c.Id)
select new
{
c.Name,
UserName = c.Name
};
foreach (var user in list)
{
Console.WriteLine($"{user.Name}-{user.UserName}");
}
}
}
using (WPFCustomerDbContext dbContext = new WPFCustomerDbContext())
{
{
try
{
string sql = "Update dbo.SysUser Set Password='Ricahrd老师-小王子' WHERE Id=@Id";
SqlParameter parameter = new SqlParameter("@Id", 1);
int flag = dbContext.Database.ExecuteSqlRaw(sql, parameter);
}
catch (Exception ex)
{
throw ex;
}
}
}
using (WPFCustomerDbContext dbContext = new WPFCustomerDbContext())
{
{
IDbContextTransaction trans = null;
try
{
trans = dbContext.Database.BeginTransaction();
string sql = "Update dbo.SysUser Set Password='Test00xx' WHERE Id=@Id";
SqlParameter parameter = new SqlParameter("@Id", 1);
dbContext.Database.ExecuteSqlRaw(sql, parameter);
string sql1 = "Update dbo.SysUser Set Password='Test00abc' WHERE Id=@Id";
SqlParameter parameter1 = new SqlParameter("@Id", 2);
dbContext.Database.ExecuteSqlRaw(sql1, parameter1);
trans.Commit();
}
catch (Exception ex)
{
if (trans != null)
trans.Rollback();
}
finally
{
trans.Dispose();
}
}
}
#endregion
ORM框架如何转出Sql语句
第一种通过SQL Server
第二种
导航属性、状态跟踪
//贪婪加载
using (WPFCustomerDbContext context = new WPFCustomerDbContext())
{
导航属性
//{
// Company? company = context.Companies.FirstOrDefault(c => c.Id == 2);
// Company? company1 = context.Companies.Include(c => c.Users).FirstOrDefault(c => c.Id == 2);
// //var sysUserLis = context.SysUsers.Include(c => c.Company).Where(c => c.Id < 19);
// //foreach (var user in sysUserLis)
// //{
// // Console.WriteLine($"User.Name={user.Name}");
// // Company company2 = user.Company;
// // Console.WriteLine($"company2.Name={company2.Name}");
// // foreach (var user2 in company2.Users)
// // {
// // Console.WriteLine($"user2.Name={user2.Name}");
// // Company company3 = user2.Company;
// // Console.WriteLine($"company2.Name={company3.Name}");
// // }
// //}
//}
一、贪婪加载! 一定查询出导航属性、引用属性中的数据
必须要Include:贪婪加载!
查询的时候,必须要Include,才能查询到对应导航属性和引用属性的相关数据
导航属性,我有需要的时候,可能会查询,有的情况下,又不需要查询~
如何满足以上诉求呢?
}