zoukankan      html  css  js  c++  java
  • 【EntityFramework Core】实体实例化注入

    由于逻辑需要,我希望能在EF Core实例化实体时,拿到实体并执行相关代码,所以我就研究了一番EF Core,得到以下方法。

    1.创建实体初始化类,继承EntityMaterializerSource

        public class ComBoostEntityMaterializerSource : EntityMaterializerSource
        {
            public ComBoostEntityMaterializerSource(IMemberMapper memberMapper) : base(memberMapper)
            {}
        }
    

    这个类是,我们需要注入到EF Core当中去的。

    2.创建EF Core扩展

        public class ComBoostOptionExtension : IDbContextOptionsExtension
        {
            public void ApplyServices(IServiceCollection services)
            {
                services.AddScoped<IEntityMaterializerSource, ComBoostEntityMaterializerSource>();
            }
        }
    

    创建扩展后,在ApplyServices里注入我们创建的初始化类。

    3.用于实例化DbContext时的DbContextOptions参数,需要添加我们创建的扩展

    new DbContextOptionsBuilder<DataContext>().UseSqlServer(Configuration.GetConnectionString("DataContext")).Options.WithExtension(new ComBoostOptionExtension()))
    

    4.重写我们的实体初始化类

        public class ComBoostEntityMaterializerSource : EntityMaterializerSource
        {
            public ComBoostEntityMaterializerSource(IMemberMapper memberMapper, CurrentDatabaseContext current) : base(memberMapper)
            {
    //已注入的,用于业务的获取当前数据库上下文的类 _database = current.Context; } private IDatabaseContext _database;
    //创建实例化实体的表达式 public override Expression CreateMaterializeExpression(IEntityType entityType, Expression valueBufferExpression, int[] indexMap = null) {
    //获取基类实例化表达式 BlockExpression expression = (BlockExpression)base.CreateMaterializeExpression(entityType, valueBufferExpression, indexMap);
    //业务逻辑判断是否是我需要更改的实体 if (typeof(IEntity).IsAssignableFrom(entityType.ClrType)) { var entityContext = _database.GetDynamicContext(entityType.ClrType);
    //属性表达式 var property = Expression.Property(expression.Variables[0], typeof(IEntity).GetProperty("EntityContext"));
    //赋值表达式 var assign = Expression.Assign(property, Expression.Constant(entityContext));
    //把几类的实例化表达式变成列表方便插入 var list = expression.Expressions.ToList();
    //因为最后一个表达式是返回实体实例
    //所以我们的逻辑代码要放在最后一条语句之前 list.Insert(list.Count - 1, assign);
    //重新生成表达式 expression = Expression.Block(expression.Variables, list); } return expression; } }

    下面是效果展示

    1.User类有一个显式实现的属性

    2.正常赋值

    3.注入后

    4.效果

  • 相关阅读:
    dotnet 使用 MessagePack 序列化对象
    dotnet 使用 MessagePack 序列化对象
    PHP die() 函数
    PHP defined() 函数
    PHP define() 函数
    PHP constant() 函数
    PHP connection_status() 函数
    查看物理CPU个数、核数、逻辑CPU个数
    CF997C Sky Full of Stars
    dotnet 使用 lz4net 压缩 Stream 或文件
  • 原文地址:https://www.cnblogs.com/Kation/p/efcore_entity_init_inject.html
Copyright © 2011-2022 走看看