当前位置:   article > 正文

【C# .NET 】使用 Entity Framework Core 操作sqlite数据库_microsoft.entityframeworkcore.sqlite

microsoft.entityframeworkcore.sqlite

1.使用工具生成数据库对应的C# 类

添加包 EF Core design package   NuGet Gallery | Home

使用用于 EF Core 迁移现有数据库中的反向工程(基架)的工具需要安装相应的工具包:

请参阅 Entity Framework Core 工具参考,详细了解如何使用 EF Core 工具,包括如何在项目中或在全局范围内正确安装 dotnet-ef 工具。

2.生成的对应类库

2.1 数据库上下文类

  1. using System;
  2. using Microsoft.EntityFrameworkCore;
  3. using Microsoft.EntityFrameworkCore.Metadata;
  4. #nullable disable
  5. namespace Packt.Shared.AutoGen
  6. {//DbContext 实例表示与数据库的会话,可用于查询和保存实体的实例。 DbContext 是工作单元和存储库模式的组合。
  7. public partial class Northwind : DbContext
  8. {
  9. public Northwind()
  10. {
  11. }
  12. public Northwind(DbContextOptions<Northwind> options)
  13. : base(options)
  14. {
  15. }
  16. public virtual DbSet<Category> Categories { get; set; } //数据集 类别
  17. public virtual DbSet<Product> Products { get; set; }//数据集: 产品
  18. /*
  19. 提供用于配置 Microsoft.EntityFrameworkCore.DbContextOptions 的简单 API 图面。
  20. 数据库(和其他扩展)通常在此对象上定义扩展方法,允许您配置要用于上下文的数据库连接(和其他选项)。
  21. 您可以使用 Microsoft.EntityFrameworkCore.DbContextOptionsBuilder 通过覆盖
  22. Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
  23. 或在外部创建 Microsoft.EntityFrameworkCore.DbContextOptions 并将其传递给上下文构造函数来配置上下文。
  24. */
  25. protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  26. {
  27. if (!optionsBuilder.IsConfigured)
  28. {//为了保护连接字符串中的潜在敏感信息,您应该将其移出源代码。 您可以使用 Name= 语法从配置中读取连接字符串,从而避免构建连接字符串 - 请参阅 https://go.microsoft.com/fwlink/?linkid=2131148。 有关存储连接字符串的更多指导,请参阅 http://go.microsoft.com/fwlink/?LinkId=723263。
  29. #warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
  30. optionsBuilder.UseSqlite("Filename=Northwind.db");
  31. }
  32. }
  33. //创建模型+
  34. protected override void OnModelCreating(ModelBuilder modelBuilder)
  35. {
  36. modelBuilder.Entity<Category>(entity =>
  37. {
  38. entity.Property(e => e.CategoryId)
  39. .ValueGeneratedNever()
  40. .HasColumnName("CategoryID");
  41. entity.Property(e => e.CategoryName).HasAnnotation("Relational:ColumnType", "nvarchar (15)");
  42. entity.Property(e => e.Description).HasAnnotation("Relational:ColumnType", "ntext");
  43. entity.Property(e => e.Picture).HasAnnotation("Relational:ColumnType", "image");
  44. });
  45. modelBuilder.Entity<Product>(entity =>
  46. {
  47. entity.Property(e => e.ProductId)
  48. .ValueGeneratedNever()
  49. .HasColumnName("ProductID");
  50. entity.Property(e => e.CategoryId)
  51. .HasColumnName("CategoryID")
  52. .HasAnnotation("Relational:ColumnType", "int");
  53. entity.Property(e => e.Discontinued)
  54. .HasDefaultValueSql("0")
  55. .HasAnnotation("Relational:ColumnType", "bit");
  56. entity.Property(e => e.ProductName).HasAnnotation("Relational:ColumnType", "nvarchar (40)");
  57. entity.Property(e => e.QuantityPerUnit).HasAnnotation("Relational:ColumnType", "nvarchar (20)");
  58. entity.Property(e => e.ReorderLevel)
  59. .HasDefaultValueSql("0")
  60. .HasAnnotation("Relational:ColumnType", "smallint");
  61. entity.Property(e => e.SupplierId)
  62. .HasColumnName("SupplierID")
  63. .HasAnnotation("Relational:ColumnType", "int");
  64. entity.Property(e => e.UnitPrice)
  65. .HasDefaultValueSql("0")
  66. .HasAnnotation("Relational:ColumnType", "money");
  67. entity.Property(e => e.UnitsInStock)
  68. .HasDefaultValueSql("0")
  69. .HasAnnotation("Relational:ColumnType", "smallint");
  70. entity.Property(e => e.UnitsOnOrder)
  71. .HasDefaultValueSql("0")
  72. .HasAnnotation("Relational:ColumnType", "smallint");
  73. });
  74. OnModelCreatingPartial(modelBuilder);
  75. }
  76. partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
  77. }
  78. }

2.2 类别类:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.DataAnnotations;
  4. using System.ComponentModel.DataAnnotations.Schema;
  5. using Microsoft.EntityFrameworkCore;
  6. #nullable disable
  7. namespace Packt.Shared.AutoGen
  8. {
  9. [Index(nameof(CategoryName), Name = "CategoryName")]
  10. public partial class Category
  11. {
  12. public Category()
  13. {
  14. Products = new HashSet<Product>();
  15. }
  16. [Key]
  17. [Column("CategoryID")]
  18. public long CategoryId { get; set; }
  19. [Required]
  20. [Column(TypeName = "nvarchar (15)")]
  21. public string CategoryName { get; set; }
  22. [Column(TypeName = "ntext")]
  23. public string Description { get; set; }
  24. [Column(TypeName = "image")]
  25. public byte[] Picture { get; set; }
  26. [InverseProperty(nameof(Product.Category))]
  27. public virtual ICollection<Product> Products { get; set; }
  28. }
  29. }

2.3 产品类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.DataAnnotations;
  4. using System.ComponentModel.DataAnnotations.Schema;
  5. using Microsoft.EntityFrameworkCore;
  6. #nullable disable
  7. namespace Packt.Shared.AutoGen
  8. {
  9. [Index(nameof(CategoryId), Name = "CategoriesProducts")]
  10. [Index(nameof(CategoryId), Name = "CategoryID")]
  11. [Index(nameof(ProductName), Name = "ProductName")]
  12. [Index(nameof(SupplierId), Name = "SupplierID")]
  13. [Index(nameof(SupplierId), Name = "SuppliersProducts")]
  14. public partial class Product
  15. {
  16. [Key]
  17. [Column("ProductID")]
  18. public long ProductId { get; set; }
  19. [Required]
  20. [Column(TypeName = "nvarchar (40)")]
  21. public string ProductName { get; set; }
  22. [Column("SupplierID", TypeName = "int")]
  23. public long? SupplierId { get; set; }
  24. [Column("CategoryID", TypeName = "int")]
  25. public long? CategoryId { get; set; }
  26. [Column(TypeName = "nvarchar (20)")]
  27. public string QuantityPerUnit { get; set; }
  28. [Column(TypeName = "money")]
  29. public byte[] UnitPrice { get; set; }
  30. [Column(TypeName = "smallint")]
  31. public long? UnitsInStock { get; set; }
  32. [Column(TypeName = "smallint")]
  33. public long? UnitsOnOrder { get; set; }
  34. [Column(TypeName = "smallint")]
  35. public long? ReorderLevel { get; set; }
  36. [Required]
  37. [Column(TypeName = "bit")]
  38. public byte[] Discontinued { get; set; }
  39. [ForeignKey(nameof(CategoryId))]
  40. [InverseProperty("Products")]
  41. public virtual Category Category { get; set; }
  42. }
  43. }

3. 数据库的操作

  1. using static System.Console;
  2. using Packt.Shared;
  3. using Microsoft.EntityFrameworkCore;
  4. using System.Linq;
  5. using System;
  6. using Microsoft.EntityFrameworkCore.Infrastructure;
  7. using Microsoft.Extensions.DependencyInjection;
  8. using Microsoft.Extensions.Logging;
  9. using System.Collections.Generic;
  10. using Microsoft.EntityFrameworkCore.Storage;
  11. namespace WorkingWithEFCore
  12. {
  13. class Program
  14. { //查询类别
  15. static void QueryingCategories()
  16. {
  17. using (var db = new Northwind())
  18. { //从实现 Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure`1 的类型公开的 System.IServiceProvider 解析服务。
  19. // 此方法通常由数据库提供程序(和其他扩展)使用。 它通常不在应用程序代码中使用。
  20. //Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure`1 用于隐藏不打算在应用程序代码中使用
  21. //但可用于数据库提供程序编写的扩展方法等的属性。
  22. var loggerFactory = db.GetService<ILoggerFactory>();
  23. loggerFactory.AddProvider(new ConsoleLoggerProvider());//将 Microsoft.Extensions.Logging.ILoggerProvider 添加到日志系统。
  24. WriteLine("Categories and how many products they have:");
  25. // a query to get all categories and their related products
  26. IQueryable<Category> cats;//获取所有类别及其相关产品的查询
  27. // = db.Categories;
  28. // .Include(c => c.Products);
  29. //获取或设置一个值,该值指示是否将在首次访问时加载被跟踪实体的导航属性。
  30. // 默认值是true。 但是,延迟加载只会发生在实体的导航属性中,这些实体也已在模型中配置为延迟加载。
  31. db.ChangeTracker.LazyLoadingEnabled = false;//默认true
  32. Write("Enable eager loading? (Y/N): ");//启用预加载
  33. bool eagerloading = (ReadKey().Key == ConsoleKey.Y);
  34. bool explicitloading = false;
  35. WriteLine();
  36. if (eagerloading)//预加载 产品数量非零
  37. {
  38. cats = db.Categories.Include(c => c.Products);//指定要包含在查询结果中的相关实体。 要包含的导航属性从被查询实体的类型 (TEntity) 开始指定。
  39. }
  40. else
  41. {
  42. cats = db.Categories;
  43. Write("Enable explicit loading? (Y/N): ");//Y 显式加载 产品数量非零
  44. explicitloading = (ReadKey().Key == ConsoleKey.Y);
  45. WriteLine();
  46. }
  47. foreach (Category c in cats)
  48. {
  49. if (explicitloading)//显式加载每个类别
  50. {
  51. Write($"Explicitly load products for {c.CategoryName}? (Y/N): "); //Y 产品数量输出非零
  52. ConsoleKeyInfo key = ReadKey();
  53. WriteLine();
  54. if (key.Key == ConsoleKey.Y)
  55. {
  56. var products = db.Entry(c).Collection(c2 => c2.Products);//获取类别c的 产品型号集合
  57. if (!products.IsLoaded) products.Load();
  58. }
  59. }
  60. WriteLine($"{c.CategoryName} has {c.Products.Count} products.");
  61. }
  62. }
  63. }
  64. //过滤器查询 各类
  65. // 对应的各种产品中,库存量大于stock的产品有哪些?
  66. static void FilteredIncludes()
  67. {
  68. using (var db = new Northwind())
  69. {
  70. Write("Enter a minimum for units in stock: ");
  71. string unitsInStock = ReadLine();
  72. int stock = int.Parse(unitsInStock);//库存单位
  73. //查找 库存量大于stock的产品类别
  74. IQueryable<Category> cats = db.Categories
  75. .Include(c => c.Products.Where(p => p.Stock >= stock));//要求该类的产品种类中数量大于stock
  76. WriteLine($"ToQueryString: {cats.ToQueryString()}");
  77. foreach (Category c in cats)
  78. { //某类 库存大于stock的产品有哪些
  79. WriteLine($"{c.CategoryName} has {c.Products.Count} products with a minimum of {stock} units in stock.");
  80. foreach (Product p in c.Products)
  81. {
  82. WriteLine($" {p.ProductName} has {p.Stock} units in stock.");//输出产品名 产品库存
  83. }
  84. }
  85. }
  86. }
  87. //查询产品
  88. static void QueryingProducts()
  89. {
  90. using (var db = new Northwind())
  91. {
  92. var loggerFactory = db.GetService<ILoggerFactory>();
  93. loggerFactory.AddProvider(new ConsoleLoggerProvider());
  94. WriteLine("Products that cost more than a price, highest at top.");
  95. string input;
  96. decimal price; //价格
  97. do
  98. {
  99. Write("Enter a product price: ");
  100. input = ReadLine();
  101. } while (!decimal.TryParse(input, out price));//输入产品价格
  102. IQueryable<Product> prods = db.Products
  103. .Where(product => product.Cost > price) //产品单价大于price
  104. .OrderByDescending(product => product.Cost); //按照 产品单价 降序排列
  105. /*
  106. // alternative "fix"
  107. IOrderedEnumerable<Product> prods = db.Products
  108. .AsEnumerable() // force client-side execution
  109. .Where(product => product.Cost > price)
  110. .OrderByDescending(product => product.Cost);
  111. */
  112. foreach (Product item in prods)
  113. {//38: C?te de Blaye costs $263.50 and has 17 in stock.
  114. WriteLine(
  115. "{0}: {1} costs {2:$#,##0.00} and has {3} in stock.",
  116. item.ProductID, item.ProductName, item.Cost, item.Stock);
  117. }
  118. }
  119. }
  120. //like查询
  121. static void QueryingWithLike()
  122. {
  123. using (var db = new Northwind())
  124. {
  125. var loggerFactory = db.GetService<ILoggerFactory>();
  126. loggerFactory.AddProvider(new ConsoleLoggerProvider());
  127. Write("Enter part of a product name: ");
  128. string input = ReadLine();
  129. IQueryable<Product> prods = db.Products
  130. .Where(p => EF.Functions.Like(p.ProductName, $"%{input}%"));//包含 {input} 的 产品名
  131. foreach (Product item in prods)
  132. {
  133. WriteLine("{0} has {1} units in stock. Discontinued? {2}",
  134. item.ProductName, item.Stock, item.Discontinued);
  135. }
  136. }
  137. }
  138. //添加产品
  139. static bool AddProduct(int categoryID, string productName, decimal? price)
  140. {
  141. using (var db = new Northwind())
  142. {
  143. var newProduct = new Product
  144. {
  145. CategoryID = categoryID,//类别id 产品id自增加
  146. ProductName = productName,
  147. Cost = price
  148. };
  149. // mark product as added in change tracking
  150. db.Products.Add(newProduct);
  151. // save tracked changes to database
  152. int affected = db.SaveChanges();//将跟踪的更改保存到数据库
  153. return (affected == 1);
  154. }
  155. }
  156. //列出产品
  157. static void ListProducts()
  158. {
  159. using (var db = new Northwind())
  160. {
  161. WriteLine("{0,-3} {1,-35} {2,8} {3,5} {4}",
  162. "ID", "Product Name", "Cost", "Stock", "Disc.");
  163. foreach (var item in db.Products.OrderByDescending(p => p.Cost))
  164. {
  165. WriteLine("{0:000} {1,-35} {2,8:$#,##0.00} {3,5} {4}",
  166. item.ProductID, item.ProductName, item.Cost,
  167. item.Stock, item.Discontinued);
  168. }
  169. }
  170. }
  171. //增加产品价格
  172. static bool IncreaseProductPrice(string name, decimal amount)
  173. {
  174. using (var db = new Northwind())
  175. {
  176. // get first product whose name starts with name
  177. Product updateProduct = db.Products.First(
  178. p => p.ProductName.StartsWith(name));
  179. updateProduct.Cost += amount;
  180. int affected = db.SaveChanges();
  181. return (affected == 1);
  182. }
  183. }
  184. //删除产品
  185. static int DeleteProducts(string name)
  186. {
  187. using (var db = new Northwind())
  188. {
  189. using (IDbContextTransaction t = db.Database.BeginTransaction())//开始一个新的事务。
  190. {
  191. WriteLine("Transaction isolation level: {0}",
  192. t.GetDbTransaction().IsolationLevel);
  193. var products = db.Products.Where(
  194. p => p.ProductName.StartsWith(name));
  195. db.Products.RemoveRange(products);
  196. int affected = db.SaveChanges();
  197. t.Commit();
  198. return affected;
  199. }
  200. }
  201. }
  202. static void Main(string[] args)
  203. {
  204. // QueryingCategories();
  205. // FilteredIncludes();
  206. //QueryingProducts();
  207. //QueryingWithLike();
  208. //if (AddProduct(6, "Bob's Burgers", 500M))
  209. //{
  210. // WriteLine("Add product successful.");
  211. //}
  212. //if (IncreaseProductPrice("Bob", 20M))
  213. //{
  214. // WriteLine("Update product price successful.");
  215. //}
  216. int deleted = DeleteProducts("Bob");
  217. WriteLine($"{deleted} product(s) were deleted.");
  218. // ListProducts();
  219. ReadLine();
  220. }
  221. }
  222. }

4. Loggin EF Core

  1. using Microsoft.Extensions.Logging;
  2. using System;
  3. using static System.Console;
  4. namespace Packt.Shared
  5. {
  6. public class ConsoleLoggerProvider : ILoggerProvider//创建日志提供器
  7. {
  8. public ILogger CreateLogger(string categoryName)
  9. {
  10. return new ConsoleLogger();//控制台记录器
  11. }
  12. // if your logger uses unmanaged resources,
  13. // you can release the memory here 如果您的记录器使用非托管资源,您可以在此处释放内存
  14. public void Dispose() { }
  15. }
  16. public class ConsoleLogger : ILogger //日志记录器
  17. {
  18. // if your logger uses unmanaged resources, you can
  19. // return the class that implements IDisposable here
  20. //如果您的记录器使用非托管资源,您可以在此处返回实现 IDisposable 的类
  21. public IDisposable BeginScope<TState>(TState state)
  22. {
  23. return null;
  24. }
  25. //为避免过度记录,您可以在日志级别上进行过滤
  26. public bool IsEnabled(LogLevel logLevel)
  27. {
  28. // to avoid overlogging, you can filter
  29. // on the log level 为避免过度记录,您可以在日志级别上进行过滤
  30. switch (logLevel)
  31. {
  32. case LogLevel.Trace:
  33. case LogLevel.Information:
  34. case LogLevel.None:
  35. return false;
  36. case LogLevel.Debug:
  37. case LogLevel.Warning:
  38. case LogLevel.Error:
  39. case LogLevel.Critical:
  40. default:
  41. return true;
  42. };
  43. }
  44. //记录日志
  45. public void Log<TState>(LogLevel logLevel,
  46. EventId eventId, TState state, Exception exception,
  47. Func<TState, Exception, string> formatter)
  48. {
  49. if (eventId.Id == 20100)
  50. {
  51. // 记录级别和事件标识符 log the level and event identifier
  52. Write($"Level: {logLevel}, Event ID: {eventId.Id}");
  53. //仅在存在时输出状态或异常 only output the state or exception if it exists
  54. if (state != null)
  55. {
  56. Write($", State: {state}");
  57. }
  58. if (exception != null)
  59. {
  60. Write($", Exception: {exception.Message}");
  61. }
  62. WriteLine();
  63. }
  64. }
  65. }
  66. }

5.  设置sqlite for windows

SQLite Download Page  下载 

sqlite-tools-win32-x86-3410200.zip
(1.91 MiB)
A bundle of command-line tools for managing SQLite database files, including the command-line shell program, the sqldiff.exe program, and the sqlite3_analyzer.exe program.
(SHA3-256: 0ceebb7f8378707d6d6b0737ecdf2ba02253a3b44b1009400f86273719d98f1f)

解压并设置环境变量(exe 所在目录添加到path)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/253461
推荐阅读
相关标签
  

闽ICP备14008679号