概览

EF Core 6.0 是建立在ADO.NET框架之上的,它下面仍旧使用了ADO.NET方法和类来执行数据操作。DbContext负责将sqlite翻译成sqlite,跟踪数据状态。

EF Core  6.0底层是Miscrosoft.Data.sqlite。DbContext,这个类是EF Code First的核心,在高层次上是数据库抽象,DbContext是一级缓存。DBSet类表示一个实体的集合,用来创建、更新、删除、查询操作,DBSet<TEntity>是DBSet的泛型版本,可以使用DbContext获取DBSet的引用,例如dbContext.PersonInfos

 

DbSet与DbContext数据更新奥秘

将实体映射到数据表格方式有两种:特性和Fluent API

实体特性(Data Annonation  标注)

学习顺序

1、了解ORM概念、POCO 类型、linq、mvvm模式

2、了解EF Core 6.0的历史、为什么要使用EF Core、Entity Framework的三种开发风格

3、了解DbSet与DbContext、模型、配置模型

4、DbSet crud操作 ,详细查看https://learn.microsoft.com/zh-cn/ef/core/performance/advanced-performance-topics?tabs=with-di%2Cwith-constant#dbcontext-pooling

5、了解EF Core 6.0 的性能极限

 

开始实操(CodeFirst的数据库初始化)

1)环境:vs2022+.net6.0+EF Core 6.0 +sqlite3+mvvm模式

2)创建WPF应用程序MvvmDemo并且安装实体框架 NuGet 包 Microsoft.EntityFrameworkCore.qlite(6.0.9)、安装 Sqlite 包后,并且安装Microsoft.EntityFrameworkCore 基础包。可以选择安装 Microsoft.EntityFrameworkCore.Proxies 包提供对“延迟加载”数据的支持。

 

3)创建sqlite数据库Data.db和PersonInfo表

 

 

 

4)C# 创建实体模型 PersonInfo.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;

namespace MvvmDemo.Mvvm.Models
{
    public class Student
    {
        [Key]
        public string Name { get; set; }
        public string Age { get; set; }
    }
    public class PersonInfo : IDataErrorInfo
    {
        /// <summary>
        /// 对应数据库中 表格
        /// </summary>
        /// 
        #region 实体 
        private string? _email; //字段不会有映射到数据库的表格
        private string? _firstName;
        private string? _lastName;

        [Column("Company")]   //对应数据库中表的列
        public string? Company { get; set; }

        [Column("FirstName")]   //对应数据库中表的列
        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = value;
            }
        }

        [Column("LastName")]  //对应数据库中表的列
        public string? LastName
        {
            get { return _lastName; }
            set
            {
                _lastName = value;
            }
        }

        [Column("Email")]  //对应数据库中表的列
        [Key]//主键
        public string Email { get; set; }

        [Column("IsCompany")]  //对应数据库中表的列
        public bool IsCompany { get; set; } = false;

        [Column("TotalSales")]  //对应数据库中表的列
        public double? TotalSales { get; set; }

      
        #endregion

        //不映射到对应数据库中表的列
        public bool IsValid
        {
            get
            {

                foreach (string item in ValidationProperties)
                {
                    if (string.IsNullOrEmpty(ValidationError(item)))
                        return true;

                }

                return false;
            }
        }
        [NotMapped]  //不映射到对应数据库中表的列
        public string? IsSelected { get; set; }

        public PersonInfo()
        {

        }

        string IDataErrorInfo.Error => throw new NotImplementedException();//用于表格的行验证

        //用于单元格属性验证
        string IDataErrorInfo.this[string propertyName] => ValidationError(propertyName);

        private string? ValidationError(string propertyName)
        {
            //哪些属性需要验证
            if (Array.IndexOf(ValidationProperties, propertyName) < 0) return null;

            switch (propertyName)
            {
                case "FirstName":
                    return ValidationFirstName();

                case "LastName":
                    return ValidationLastName();

                case "Company":
                    return ValidationCompany();

                case "Email":
                    return ValidationEmail();



                default: return "";


            }
        }

   
      
        private string? ValidationEmail()
        {
            if (String.IsNullOrEmpty(_email)) return GetPropertyValue("EmailIsNotNull");
            string partn = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$"; ;
            if (!Regex.IsMatch(_email, partn, RegexOptions.IgnoreCase))
            {
                return GetPropertyValue("EmailFormatIsError");
            }
            return null;

        }

        private string ValidationCompany()
        {
            throw new NotImplementedException();
        }

        private string? ValidationLastName()
        {
            //本地化错误提示
            if (String.IsNullOrEmpty(_firstName)) return GetPropertyValue("FirstName_NameIsNotnull");
            if (_firstName.Length <= 5) return GetPropertyValue("FirstName_NameLengthMore5char");
            return null;

        }
        static readonly string[] ValidationProperties =
        {
            "Email",
            "FirstName",
            "LastName",

        };
        private string ValidationFirstName()
        {
            //本地化错误提示
            if (String.IsNullOrEmpty(_firstName)) return GetPropertyValue("FirstName_NameIsNotnull");
            if (_firstName.Length <= 5) return GetPropertyValue("FirstName_NameLengthMore5char");
            return "";


        }
        string GetPropertyValue(string name)
        {

            return (string)Application.Current.Resources[name];
        }

        private Dictionary<String, List<String>> errors = new Dictionary<string, List<string>>();

        public PersonInfo(string firstName, string? lastName, string email, bool isCompany, double? totalSales)
        {
            FirstName = firstName;
            LastName = lastName;
            Email = email;
            IsCompany = isCompany;
            TotalSales = totalSales;
       
        }
    }
}

 5)配置数据连接 App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <connectionStrings >
        <!--相对与当前目录的路径-->
        <add name="LoginString"
            connectionString="Data Source=D:\程序开发\观察者\mvvmdemo\MvvmDemo\MvvmDemo\Repositories\Data.db; "
            providerName="Microsoft.EntityFrameworkCore.Sqlite" />

    </connectionStrings>
</configuration>

 

6)建立实体和数据库表格映射。

     有两种方式建立实体和数据表格之间映射关系。

在自定义的上下文DataContext  中采用Fluent API方式建立实体和数据库表格映射关系。详细查看微软官网   FluentAPI详细用法

在实体中通过Attribute特性建立实体和数据库表格映射关系。详细查看微软官网

定制DataContext 上下文,模型映射(Model Mapping),用于连接数据和poco

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Sqlite;
using MvvmDemo.Mvvm.Models;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MvvmDemo.Repositories
{
    public class DataContext : DbContext
    {
        private readonly string _connection;
        public DbSet<PersonInfo> PersonInfos{get;set;}//实体表,提供给外部crud使用,PersonInfos内部有DataContext 的实例
        public DataContext()
        {
         //1、获取连接数据库的字符串
            _connection = ConfigurationManager.ConnectionStrings["LoginString"].ConnectionString;
        }
        //2、联接数据库
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite(_connection);
        }
        //3、建立实体和数据库表格 一 一 映射。  
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<PersonInfo>()
                .ToTable("PersonInfos");
        }
    }
}

7)可选配置.Net EF中DbContext动态生成DbSet

平时我们在使用EF的过程中,都是有DbContext中每一个表加一个DbSet,如果我们一个项目有上千个表,就得加上千个DbSet,是很麻烦的一个工程,现在采用一个简单的方法处理,在DbContext类的OnConfiguring方法中加上如下代码:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            var assembly = Assembly.GetExecutingAssembly(); foreach (Type type in assembly.ExportedTypes) { if (type.IsClass && type != typeof(EntityBase) && typeof(EntityBase).IsAssignableFrom(type)) { var method = modelBuilder.GetType().GetMethods().Where(x => x.Name == "Entity").FirstOrDefault(); if (method != null) { method = method.MakeGenericMethod(new Type[] { type }); method.Invoke(modelBuilder, null); } } } base.OnModelCreating(modelBuilder); }

动态加载,不用再一个一个写了,简单方便

 

 

 

原文地址:http://www.cnblogs.com/cdaniu/p/16746691.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性