要专业系统地学习 EF 推荐《你必须掌握的 Entity Framework 6.x 与 Core 2.0》. 这本书作者 (汪鹏, Jeffcky) 的博客: https://www.cnblogs.com/CreateMyself/
今天继续学习 EF, 但是看来看去, 实在是感觉不爽啊, 因为你不知道源码里面到底是什么回事, 我只能去猜去想象, 要是有源码给我看几个单词也好啊.
百度吧. 还是找到几篇博客, 看上去不是很难弄.
https://www.cnblogs.com/michaellfx/p/3806857.html
https://www.cnblogs.com/zhesong/p/EF6Debug.html
先下载 EF 的源码: https://github.com/aspnet/EntityFramework6 我不知道这是 6. 几的版本, 也不知道这是不是官方的
创建自己的控制台项目, 引入两个程序集, 并且控制台程序添加对这两个程序集的引用, 把这两个程序集的强签名去掉, 重新生成解决方案
这里要注意, 我们只引入了 EntityFramework 和 EntityFramework.SqlServer, 如果我们想要用数据迁移是不行的, 可能要还要引入其他的程序集, 我做了, 没有成功.
所以, 我们只能自己手动地去创建数据, 并且数据模型的配置也要写, 并且你要保证你的配置和手写的数据库是完全匹配的.
你可以在另一个项目中把数据模型, 配置都写好, 测试没问题, 拿到这个项目中复制.
我的三个 model
- // 基类
- public class BaseEntity
- {
- public BaseEntity()
- {
- this.Id = Guid.NewGuid().ToString();
- this.AddTime = DateTime.Now;
- }
- public string Id { get; set; }
- public DateTime AddTime { get; set; }
- }
- // 产品类
- public class Order : BaseEntity
- {
- public string OrderNO { get; set; }
- public string Description { get; set; }
- public virtual ICollection<Product> Products { get; set; }
- }
- // 产品类
- public class Product : BaseEntity
- {
- public string Name { get; set; }
- public decimal Price { get; set; }
- public string Unit { get; set; }
- public string FK_OrderId { get; set; }
- public virtual Order Order { get; set; }
- }
- View Code
配置如下
- public class EFDbContext:DbContext
- {
- public EFDbContext():base("name=ConnectionStr")
- {
- }
- public DbSet<Order> Orders { get; set; }
- public DbSet<Product> Products { get; set; }
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- modelBuilder.Entity<Order>().ToTable("tb_Orders")
- .HasKey(x => x.Id)
- .HasMany(x => x.Products)
- .WithRequired(x => x.Order)
- .HasForeignKey(x => x.FK_OrderId);
- modelBuilder.Entity<Product>().ToTable("tb_Products")
- .HasKey(x => x.Id);
- modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
- base.OnModelCreating(modelBuilder);
- }
- }
- View Code
查询数据, 打印看看
- class Program
- {
- static void Main(string[] args)
- {
- // 忽略循环引用
- JsonSerializerSettings set = new JsonSerializerSettings();
- set.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
- using (EFDbContext2 ctx = new EFDbContext2())
- {
- ctx.Database.Log = Console.WriteLine;
- var res = ctx.Products.ToList();
- Console.WriteLine(JsonConvert.SerializeObject(res,set));
- }
- }
- }
- View Code
报错, 找不到程序集
我们把源码中的这里改成 null
App.config 配置文件中也改一下, pulicKeyToken 改成 null
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <configSections>
- <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
- <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null" requirePermission="false" />
- </configSections>
- <connectionStrings>
- <add name="ConnectionStr" connectionString="Data Source=LAPTOP-G81QJ856\SQLEXPRESS;Initial Catalog=_201901202.EFDbContext;Integrated Security=True" providerName="System.Data.SqlClient"></add>
- </connectionStrings>
- <startup>
- <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
- </startup>
- </configuration>
- View Code
然后打印数据, 出来了
这里要注意一个问题, EFDbContext 中要一次性写好, 不能运行了项目, 再对 EFDbContext 进行改动, 这样他会说你的文件改动要执行数据迁移, 更新数据库. 但是我们刚刚就强调了, 只是引入了两个程序集, 无法提供数据迁移的功能
我开始就是这样, EFDbContext 中的配置没有写, 可能是 EF 无法匹配到数据库, 一直进行它的默认连接, 即使我给他指定了连接字符串(我要求他连接到_201901202.EFDbContext 这个数据库, 但是我的配置和数据不匹配, 他就连接默认数据库: 命名空间 + 上下文类名)
然后我改好 EFDbContext, 以为这下终于万无一失, 但是他说支持 "EFDbContext" 上下文的模型发生了更改. 考虑使用代码优先迁移来更新数据库. 可是我迁移用不了啊!
所以我又写了一个 EFDbContext2, 把代码复制过来, 这样终于行了, 连接到指定的数据源了.
来源: https://www.cnblogs.com/jinshan-go/p/10296665.html