• 关于Entity Framework Core 6 新增特性解读


    介绍

    本文对前面6篇Entity Framework Core 6特性的一个详细说明

    正文

    EntityTypeConfiguration 属性

    该属性是一个非常实用的属性,之前我们的写法都是这样,这样会存在一个问题,就是项目里面实体很多,就算根据业务进行了分类,要去找到被修改的实体也是个麻烦事。

     public static class SimulationsPartDbContextModelCreatingExtensions
        {
            public static void ConfigureSimulationsPart(
                this ModelBuilder builder,
                Action<SimulationsPartModelBuilderConfigurationOptions> optionsAction = null)
            {
                Check.NotNull(builder, nameof(builder));
    
                var options = new SimulationsPartModelBuilderConfigurationOptions(
                    SimulationsPartDbProperties.DbTablePrefix,
                    SimulationsPartDbProperties.DbSchema
                );
    
                optionsAction?.Invoke(options);
    
                builder.ApplyConfiguration(new SimulationCfg());
    
                builder.ApplyConfiguration(new SimulationsVersionPubCfg());
    
                builder.ApplyConfiguration(new SimulationsSummaryDataCfg());
    
                builder.ApplyConfiguration(new SimulationCommercialFormatCfg());
    
                builder.ApplyConfiguration(new SimulationBuildingCfg());
    
                builder.ApplyConfiguration(new SimulationKeyPointCfg());
    
                builder.ApplyConfiguration(new SimulationSubjectMapCfg());
    
                builder.ApplyConfiguration(new SimulationPlanIndexCfg());
    
    			builder.ApplyConfiguration(new SimulationKeyPointExCfg());
    
                builder.ApplyConfiguration(new SimulationManageIndexCfg());
    

    以后我们就将对应实体的Fluent API配置直接写在头部

    [EntityTypeConfiguration(typeof(ProductConfiguration))]
    public class Product
    {
        public int Id { get; set; }
        public decimal Price { get; set; }
        public string Name { get; set; }
    }
    

    时态表

    对于金融或财务系统的朋友应该是福音了,但是需要SqlServer 企业版,主要作用是自动跟踪表的历史状态,也就是对表中的数据创建一个历史记录,非常适合追踪数据和恢复数据,

    https://docs.microsoft.com/zh-cn/sql/relational-databases/tables/temporal-tables?view=sql-server-ver15

    简单来说如果我们将表设置为时态表,那么就会创建两个datetime2名为PeriodStart和的隐藏列PeriodEnd,这两个列存储的是 SQL Server 生成的 UTC 时间,时态表会创建一个关联的历史记录表.

    项目中的使用环节,比如我们要查询一个商品的历史波动,先去想想你们会怎么写,或者我要一个设备的历史数据做数据分析,

    查询历史数据

    使用时态表我们可以这样写。查询将PeriodStart和PeriodEnd值投影到匿名类型中,以及当时实体实例的快照。该方法用于获取周期值,因为它们映射到实体中的阴影属性。

    var productSnapshots = context.Products
        .TemporalBetween(from, to)
        .OrderBy(product => EF.Property<DateTime>(product, "PeriodStart"))
        .Where(product => product.Name == productName)
        .Select(product =>
            new
            {
                Product = product,
                PeriodStart = EF.Property<DateTime>(product, "PeriodStart"),
                PeriodEnd = EF.Property<DateTime>(product, "PeriodEnd")
            })
        .ToList();
    
    
    查找特定的历史记录
    var order = context.Orders
        .TemporalAsOf(on)
        .Include(e => e.Product)
        .Include(e => e.Customer)
        .Single(order =>
            order.Customer.Name == customerName
            && order.OrderDate > on.Date
            && order.OrderDate < on.Date.AddDays(1));
    
    
    // SQL
    
    FOR SYSTEM_TIME FROM '2022-01-24' TO '9999-12-31'  
    
    恢复已删除的数据
    // 找到被删除数据的时间搓
    var customerDeletedOn = context.Customers
        .TemporalAll()
        .Where(customer => customer.Name == customerName)
        .OrderBy(customer => EF.Property<DateTime>(customer, "PeriodEnd"))
        .Select(customer => EF.Property<DateTime>(customer, "PeriodEnd"))
        .Last();
    
    // 根据时间搓获取数据
        var customerAndOrders = context.Customers
        .TemporalAsOf(customerDeletedOn.AddMilliseconds(-1))
        .Include(e => e.Orders)
        .Single();
    
    // 恢复数据
    context.Add(customerAndOrders);
    context.SaveChanges();
    

    HasConversion

    这个其实没啥特别的,做过DDD的同学应该都经历过。

    public class AddressConverter : ValueConverter<Address, string>
    {
        public AddressConverter()
            : base(
                v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null),
                v => JsonSerializer.Deserialize<Address>(v, (JsonSerializerOptions)null))
        {
        }
    }
    

    命令源枚举

    这个是一个非常实用的东西,我们日常开发进行代码调试或者做一些额外配置我觉得都用得到,我看网上有用这个做读写分离的文章

    class ExampleInterceptor : DbCommandInterceptor
    {
        public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command,
            CommandEventData eventData, InterceptionResult<DbDataReader> result)
        {
            if (eventData.CommandSource == CommandSource.SaveChanges)
            {
                Console.WriteLine($"Saving changes for {eventData.Context.GetType().Name}:");
                Console.WriteLine();
                Console.WriteLine(command.CommandText);
            }
    
            if (eventData.CommandSource == CommandSource.FromSqlQuery)
            {
                Console.WriteLine($"From Sql query for {eventData.Context.GetType().Name}:");
                Console.WriteLine();
                Console.WriteLine(command.CommandText);
            }
    
            return result;
        }
    }
    
    

    结语

    联系作者:加群:867095512 @MrChuJiu

    公众号

  • 相关阅读:
    bug篇——generator逆向出现配置文件不存在
    安装篇——Linux下安装mysql
    安装篇——linux服务器安装jdk、mysql、nginx、fastdfs
    基础篇——浅谈Base64
    基础篇—AOP
    基础篇—List、Set、Map
    工具类篇——I/O读取文件
    基础篇——Spring之XML配置Bean的属性注入
    简单了解malloc分配内存
    通过指针形参修改实参的值2
  • 原文地址:https://www.cnblogs.com/MrChuJiu/p/15839670.html
Copyright © 2020-2023  润新知