回滾最近的一次遷移記錄
remove-migration 會報錯
加參數remove-migration --force
一個程序集下面存在多個DbContext 指定DbContext進行遷移
add-migration --context XXXDbContext
一個事務中 先在數據庫查出一條數據進行修改 然后在進行查詢 他會直接在內存中找到這條數據 不會再數據庫查詢了
EF Core的 linq語句中可以使用C#方法或函數 在EF6或之前版本不可以
.Include() 在EF Core和 EF6中支持lamada表達式 之前的版本該方法只接受列名字符串
使用原生sql
FormSql已棄用
using (var dataContext = new SampleDbContext()) { var query = dataContext.Categories.FromSqlRaw("select * from Category"); var result = query.ToList(); }
通過這種方式拼接sql 會自動拼接成帶參數的sql語句
var query = dataContext.Categories.FromSql($"select * from Category where CategoryID={categoryID}");
執行存儲過程
var query = dataContext.Categories.FromSql($"GetCategoryById {categoryID}");
配置一對一關系 在EF6.X或之前不支持
public class Student { public int Id { get; set; } public string Name { get; set; } public StudentAddress Address { get; set; } } public class StudentAddress { public int StudentAddressId { get; set; } public string Address { get; set; } public string City { get; set; } public string State { get; set; } public string Country { get; set; } public int StudentId { get; set; } public Student Student { get; set; } }
在Student表中自動產生一個AddressId列
訂單行關聯訂單頭可以省略前兩行代碼 直接寫最后一行
public class SalesOrderLine : Entity<Guid> { /// <summary> /// 銷售訂單ID /// </summary> public virtual Guid? SalesOrderId { set; get; } /// <summary> /// 銷售訂單 /// </summary> [ForeignKey(nameof(SalesOrderId))] public virtual SalesOrder SalesOrder { set; get; }
EF中已經有了默認的約定來實現一對多 如果想要自己寫 可以擴展 Fluent API 這些一對多的配置在EF約定中就已經實現了 不需要自己配置 可以通過這個配置來實現級聯刪除
//配置訂單頭實體和訂單行實體的關系 modelBuilder.Entity<SalesOrder>() //訂單頭實體對象包含了 多個的訂單行 .HasMany<SalesOrderLine>(t => t.Lines) //訂單行實體對象包含了 唯一的個訂單頭 .WithOne(g => g.SalesOrder) //通過行的SalesOrderId屬性進行關聯 .HasForeignKey(g => g.SalesOrderId); //反過來配置 modelBuilder.Entity<SalesOrderLine>() //訂單行實體對象包含了 唯一的訂單頭 .HasOne<SalesOrder>(t => t.SalesOrder) //訂單頭實體對象包含了 多個訂單行 .WithMany(g => g.Lines) //通過行的SalesOrderId屬性進行關聯 .HasForeignKey(t => t.SalesOrderId);
級聯刪除
//級聯刪除 //前面的配置都一樣 只要在最后加上OnDelete modelBuilder.Entity<SalesOrder>() .HasMany<SalesOrderLine>(t => t.Lines) .WithOne(g => g.SalesOrder) .HasForeignKey(g => g.SalesOrderId) .OnDelete(DeleteBehavior.Cascade); //Cascade 刪除主實體時將刪除從屬實體 //ClientSetNull 刪除主實體時將從屬實體的的外鍵屬性值設置為null //Restrict 防止級聯刪除 //SetNull 刪除主實體時將從屬實體的的外鍵屬性值設置為null
多對多的關系只能自己配置
Entity Framework Core中沒有可自動配置多對多關系的默認約定。您必須使用Fluent API對其進行配置。
學生表
public class Student { public int StudentId { get; set; } public string Name { get; set; } public IList<StudentCourse> StudentCourses { get; set; } } 課程表 public class Course { public int CourseId { get; set; } public string CourseName { get; set; } public string Description { get; set; } public IList<StudentCourse> StudentCourses { get; set; } }
//通過一張中間表來實現學生跟課程的多對多關系
public class StudentCourse { public int StudentId { get; set; } public Student Student { get; set; } public int CourseId { get; set; } public Course Course { get; set; } }
關系配置
modelBuilder.Entity<StudentCourse>().HasKey(sc => new { sc.StudentId, sc.CourseId });
獲取當前跟蹤的所有實體
context.ChangeTracker.Entries()
可以使用 FromSql 擴展方法基於原生 SQL 查詢開始 LINQ 查詢。
var blogs = context.Blogs .FromSql("SELECT * FROM dbo.Blogs") .ToList();
原生 SQL 查詢可用於執行存儲過程。
var blogs = context.Blogs .FromSql("EXECUTE dbo.GetMostPopularBlogs") .ToList();
單獨配置給某一個實體添加租戶過濾和軟刪除過濾
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>().Property<string>("TenantId").HasField("_tenantId"); // Configure entity filters modelBuilder.Entity<Blog>().HasQueryFilter(b => EF.Property<string>(b, "TenantId") == _tenantId); modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted); }
指定當前實體框架Linq查詢不應用任何模型級實體查詢篩選器。 不應用配置的軟刪除過濾和租戶過濾
blogs = db.Blogs .Include(b => b.Posts) .IgnoreQueryFilters() .ToList();
程序和數據庫中對應類型
關於在ABP中 是否手動寫await customerRepository.UpdateAsync(cc); 更新這行代碼的測試 (不寫EF會自動監測到所有修改的字段 進行更新 , 寫了會更新所有字段)
1.不寫這行代碼 讓事務自動提交
在數據庫監控日志中會產生兩條sql語句記錄 一條是查詢 一條是更新 更新的語句只更新修改過的字段
2.寫了這行代碼
在數據庫監控日志中只有一條sql語句記錄 查詢和更新是在一起的 但是更新了所有字段
關於ef的遷移文件
add-migration 通過對比DBContext中的實體和總快照文件來生成遷移文件
update-database 會查詢__EFMigrationsHistory表中的遷移記錄 知道了最后一次遷移記錄 把這次一次之后的所有遷移文件都執行一遍
ModelSnapshot遷移快照文件 每次通過add-migration生成新的遷移文件的時候 會對比dbContext中的實體跟快照中的記錄 以這個為標准來產生新的遷移文件
遷移文件 :通過對比DBContext中的實體和快照文件來生成遷移文件
當前遷移文件中有兩個方法:一個是Up Up就是使用update-database是執行的代碼段 Down是回滾遷移文件執行的代碼段 Up跟Down的的代碼段肯定是相反的 比如在Up中新增一張表 在Down中就是刪除這張表
遷移文件下面還有一個.Designer的文件 執行當前遷移文件后的快照文件
創建新庫的時候: 因為不存在遷移記錄表 所以會把所有遷移文件按順序執行一遍 如果有丟失的遷移文件 則可能報錯 遷移失敗
修改庫:找到當前遷移表中記錄的遷移文件 執行在這之后新增的所有遷移文件
自動遷移
dbContext.Database.EnsureCreated();//不存在數據庫則執行遷移 不執行更新操作
dbContext.Database.Migrate();每次都執行遷移文件 有最新就更新
https://docs.microsoft.com/zh-cn/ef/core/saving/cascade-delete
http://www.entityframeworktutorial.net/efcore/querying-in-ef-core.aspx