新建.NET CORE CONSOLE控制台項目NetCoreConsole,管理NuGet程序包種添加一下引用
//Microsoft.EntityFrameworkCore //EFCore //Microsoft.Extensions.Logging // 日志 //Microsoft.Extensions.Logging.Console // 日志輸出到Console控制台 //Microsoft.Extensions.Logging.Debug // 日志輸出到調試Debug //Microsoft.EntityFrameworkCore.Proxies// 懶加載,延遲加載,EFCore沒有懶加載,使用該庫,可以實現懶加載 //Microsoft.EntityFrameworkCore.SqlServer//EFCore使用的SqlServer數據庫 //Pomelo.EntityFrameworkCore.MySql//EFCore使用的MySql數據庫
項目代碼如下:
using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using Microsoft.Extensions.Logging; using System.Linq; using System.Diagnostics; using Microsoft.EntityFrameworkCore.Storage; //Microsoft.EntityFrameworkCore //EFCore //Microsoft.Extensions.Logging // 日志 //Microsoft.Extensions.Logging.Console // 日志輸出到Console控制台 //Microsoft.Extensions.Logging.Debug // 日志輸出到調試Debug //Microsoft.EntityFrameworkCore.Proxies// 懶加載,延遲加載,EFCore沒有懶加載,使用該庫,可以實現懶加載 //Microsoft.EntityFrameworkCore.SqlServer//EFCore使用的SqlServer數據庫 //Pomelo.EntityFrameworkCore.MySql//EFCore使用的MySql數據庫 namespace NetCoreConsole { class Program { static void Main(string[] args) { Console.WriteLine("測試 EF core "); BlogContext blogContext = new BlogContext(); #region ef 數據庫的創建和刪除 //Console.WriteLine("刪除數據庫"); //blogContext.Database.EnsureDeleted(); //Console.WriteLine("添加數據庫"); blogContext.Database.EnsureCreated(); //Console.WriteLine("添加數據庫成功"); #endregion #region 數據遷移相關 //IEnumerable<string> vs = blogContext.Database.GetMigrations(); //blogContext.Database.GetPendingMigrations(); //blogContext.Database.GetAppliedMigrations(); //blogContext.Database.Migrate(); //Console.WriteLine("添加數據庫成功"); #endregion #region 預先加載,懶加載 //預先加載(貪婪加載,飢餓加載,一次行加載所有) //var list = blogContext.Blog.Include(op => op.Posts).ThenInclude(op => op.Author).ToList(); //var list = blogContext.Blog.Include(op => op.Posts).ThenInclude(op => op.Author).ToList(); //var list = blogContext.Blog.Include(op => op.Posts).ThenInclude(op => op.Author).ToList().AsQueryable(); //foreach (var item in list) //{ // Console.WriteLine($"blog:{item}"); // foreach (var it in item.Posts) // { // Console.WriteLine($"Posts:{it.Title}"); // Console.WriteLine($"person:{it.Author.Name}"); // } //} //懶加載(延遲加載),又稱按需加載,net ef core 默認時候沒有懶加載的, //ef是有的,ef core 要使用懶加載,需要使用proxy代理類UseLazyLoadingProxies,並且導航屬性要添加Virtual標記 //optionsBuilder.UseLazyLoadingProxies() #endregion #region IQueryable和IEnumerable不同 //IQueryable和IEnumerable不同 //IQueryable和IEnumerable都是linq操作 //IQueryable和IEnumerable都是延遲執行,tolist的時候在執行 //只不過操作的位置不同,IQueryable是在數據庫一側操作,而IEnumerable實在應用程序的內存一側操作, //IQueryable繼承IEnumerable,IQueryable與IEnumerable 可以相互轉換,IQueryable.AsIEnumerable,IEnumerable.AsIQueryable //var item = blogContext.Post.OrderBy(op => EF.Property<object>(op, "Title")).AsQueryable().Skip(1).Take(2); //IQueryable 在數據庫中的 執行腳本,IQueryable和IEnumerable都是延遲執行,tolist的時候在執行 //exec sp_executesql N'SELECT [p].[PostId], [p].[BlogId], [p].[Content], [p].[PersonId], [p].[Title] //FROM[Post] AS[p] //ORDER BY[p].[Title] //OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY',N'@__p_0 int,@__p_1 int',@__p_0=1,@__p_1=2 //foreach (var it in item) //{ // Console.WriteLine($"it:{it.Title}"); //} //var item = blogContext.Post.OrderBy(op => op.Title).AsEnumerable().Skip(1).Take(2); //IEnumerable在內存中的 執行腳本,IQueryable和IEnumerable都是延遲執行,tolist的時候在執行 //SELECT[p].[PostId], [p].[BlogId], [p].[Content], [p].[PersonId], [p].[Title] //FROM[Post] AS[p] //ORDER BY[p].[Title] //foreach (var it in item) //{ // Console.WriteLine($"it:{it.Title}"); //} #endregion #region 實體跟蹤Tracking //一種是全局修改之后在修改回來 //另外一種是,是使用AsNoTracking()直接修改 //blogContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; ////using (IDbContextTransaction transaction = blogContext.Database.BeginTransaction()) ////{ //var item = blogContext.Post.Where(op => op.Title.Contains("10")); ////var item = blogContext.Post.AsNoTracking().Where(op => op.Title.Contains("10")); //foreach (var it in item) // { // Console.WriteLine($"it:{it.Title}"); // it.Title = "111"; // } // blogContext.SaveChanges(); //// transaction.Commit(); ////} //blogContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll; #endregion #region 模糊查詢StartsWith,,EndsWith,Contains,其中Contains和 EF.Functions.Like功能一樣,但是sql語句翻譯的確實不一樣的 ////但凡使用的計算函數,索引是一定不會被用上的 //var item = blogContext.Post.Where(op => op.Title.Contains("10")).ToList(); //// SELECT[p].[PostId], [p].[BlogId], [p].[Content], [p].[PersonId], [p].[Title] //// FROM[Post] AS[p] //// WHERE CHARINDEX(N'10', [p].[Title]) > 0 //foreach (var it in item) //{ // Console.WriteLine($"it:{it.Title}"); //} //item = blogContext.Post.Where(op => EF.Functions.Like(op.Title, "%10%")).ToList(); //// SELECT[p].[PostId], [p].[BlogId], [p].[Content], [p].[PersonId], [p].[Title] //// FROM[Post] AS[p] //// WHERE[p].[Title] //// LIKE N'%10%' //foreach (var it in item) //{ // Console.WriteLine($"it:{it.Title}"); //} #endregion #region 自定義標量函數,linq一樣可以翻譯成對應的sql腳本 //// SELECT[p].[PostId] AS[id], [dbo].[MyFunction] ([p].[PostId]) AS[name] ////FROM[Post] AS[p] //var item = blogContext.Post.Select(op => new //{ // id = op.PostId, // name = BlogContext.MyFunction(op.PostId)//使用標量函數 //}).ToList(); //foreach (var it in item) //{ // Console.WriteLine($"it:{it.name}"); //} #endregion #region 編譯查詢 #region 普通查詢 //int id = 1; //Stopwatch stopwatch = new Stopwatch(); //stopwatch.Start(); //var item = blogContext.Post.Where(op => op.PostId == id).FirstOrDefault(); //stopwatch.Stop(); //Console.WriteLine($"普通查詢:item:{item.Title},用時:{stopwatch.ElapsedMilliseconds}"); // exec sp_executesql N'SELECT TOP(1) [p].[PostId], [p].[BlogId], [p].[Content], [p].[PersonId], [p].[Title] //FROM[Post] AS[p] //WHERE[p].[PostId] = @__id_0',N'@__id_0 int',@__id_0=1 #endregion #region 編譯查詢 //Stopwatch stopwatch = new Stopwatch(); //stopwatch.Start(); ////var compileQuery = EF.CompileQuery((BlogContext context, int id) => context.Post.Where(c => c.PostId == id).FirstOrDefault()); ////var item = compileQuery(blogContext, 1); //stopwatch.Stop(); //Console.WriteLine($"普通查詢:item:{item.Title},用時:{stopwatch.ElapsedMilliseconds}"); #endregion //普通查詢 Func<BlogContext, Blog> unCompileQuery = context => context.Blog.Include(c => c.Posts).Where(a => a.BlogId == 1).FirstOrDefault(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Console.WriteLine("普通查詢開始"); for (int i = 0; i < 100000; i++) { var a = unCompileQuery(blogContext); } stopwatch.Stop(); Console.WriteLine($"編譯查詢 用時:{stopwatch.ElapsedMilliseconds} 毫秒"); //編譯查詢 一般是大量數據查詢,並且參數不變的情況下比較好,但是不能返回集合 //Stopwatch stopwatch = new Stopwatch(); //stopwatch.Start(); //Console.WriteLine("編譯查詢開始"); //var compileQuery = EF.CompileQuery((BlogContext context, int id) => context.Blog.Include(c => c.Posts).Where(a => a.BlogId == 1).FirstOrDefault()); //for (int i = 0; i < 100000; i++) //{ // var item = compileQuery(blogContext, 1); //} //stopwatch.Stop(); //Console.WriteLine($"編譯查詢 用時:{stopwatch.ElapsedMilliseconds} 毫秒"); #endregion //var item = blogContext.Post.Where(op => op.Title.Contains("10")); //foreach (var it in item) //{ // Console.WriteLine($"it:{it.Title}"); //} //var item = blogContext.Post.Where(op => EF.Functions.Like(op.Title,"10")); //foreach (var it in item) //{ // Console.WriteLine($"it:{it.Title}"); //} Console.Read(); } } public class BlogContext : DbContext { public DbSet<Blog> Blog { get; set; } public DbSet<Post> Post { get; set; } public static readonly ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddConsole().AddDebug()); protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { //optionsBuilder.UseLoggerFactory(loggerFactory);//添加把數據庫操作的信息輸出到指定的控制台 //optionsBuilder.UseLazyLoadingProxies().UseSqlServer(@"server=127.0.0.1;database=mynetcore;user=sa;password=sa123;"); //Microsoft.EntityFrameworkCore.SqlServer optionsBuilder.UseSqlServer(@"server=127.0.0.1;database=mynetcore;user=sa;password=sa123;"); //Pomelo.EntityFrameworkCore.MySql //optionsBuilder.UseMySql(@"server=127.0.0.1;database=mynetcore;user=root;password=123456;"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { List<Post> posts = new List<Post>(); for (int i = 0; i < 20; i++) { posts.Add(new Post { PostId = i + 1, PersonId = i >= 10 ? 2 : 1, Title = $"文章標題:100{i}", Content = $"文章內容:{i}", BlogId = i >= 10 ? 2 : 1 }); } Blog blogs = new Blog { BlogId = 1, Url = "http://www.baidu.com" }; Blog blogs1 = new Blog { BlogId = 2, Url = "http://www.tianmao.com" }; Person person = new Person { PersonId = 1, Name = "123" }; Person person1 = new Person { PersonId = 2, Name = "456" }; modelBuilder.Entity<Post>().HasData(posts); modelBuilder.Entity<Blog>().HasData(blogs, blogs1); modelBuilder.Entity<Person>().HasData(person, person1); } #region 自定義標量函數 [DbFunction] public static string MyFunction(int id) { throw new NotImplementedException(); } #endregion } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public virtual List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } public virtual Blog Blog { get; set; } public int PersonId { get; set; } public virtual Person Author { get; set; } } public class Person { public int PersonId { get; set; } public string Name { get; set; } public virtual List<Post> Posts { get; set; } } }