GVKun编程网logo

EntityFramework Core查询数据基本本质(3. 查询中的数据源有哪些)

23

本文将为您提供关于EntityFrameworkCore查询数据基本本质的详细介绍,我们还将为您解释3.查询中的数据源有哪些的相关知识,同时,我们还将为您提供关于.NetCore3.1配置Pomelo

本文将为您提供关于EntityFramework Core查询数据基本本质的详细介绍,我们还将为您解释3. 查询中的数据源有哪些的相关知识,同时,我们还将为您提供关于.Net Core3.1 配置Pomelo.EntityFrameworkCore.MySql数据操作(2)、.NetCore 技术研究 - EntityFramework Core 3.0 Preview、.NetCore技术研究-EntityFramework Core 3.0 Preview、Asp.Net Core 项目 EntityFramework Core 根据登录用户名过滤数据的实用信息。

本文目录一览:

EntityFramework Core查询数据基本本质(3. 查询中的数据源有哪些)

EntityFramework Core查询数据基本本质(3. 查询中的数据源有哪些)

【导读】EntityFramework Core中、当查询出数据后,是如何将数据映射给实体的呢?本节我们预先做个基本探讨,后续给出其底层原理本质


前不久,我们在探索性能时,给出利用反射达到性能瓶颈时的方案即使用委托,如下:

var setId = (Action<Test, int>)Delegate.CreateDelegate(typeof(Action<Test, int>), null
  typeof(Test).GetProperty("Id").GetSetMethod());


上述我们通过委托方式来代替反射,可能我们也想到了另外一种方案,通过lambda构建表达式的方式


查询数据基本本质


首先我们来看看如何手动构建lambda表达式来获取或设置数据,废话不多讲,直接见代码

public static Action<T, object> Set<T>(PropertyInfo propertyInfo)
{
    var targetType = propertyInfo.DeclaringType;

    var setMethod = propertyInfo.GetSetMethod();

    var type = propertyInfo.PropertyType;

    var target = Expression.Parameter(targetType, "t");

    var value = Expression.Parameter(typeof(object), "d");

    var condition = Expression.Condition(
      Expression.Equal(value, Expression.Constant(DBNull.Value)),
      Expression.Default(type),
      Expression.Convert(value, type)
    );

    var body = Expression.Call(
       Expression.Convert(target, setMethod.DeclaringType),
       setMethod,
       condition);

    return Expression.Lambda<Action<T, object>>(body, target, value).Compile();
}


当我们获取到数据库数据时,紧接着需要将其对应列数据赋值给对应属性,此时根据列类型需构建表达式判断条件(Condition),继而调用其设置方法,最后构建整体lambda进行编译执行,对于获取基本同理,不再解释


public static Func<T, object> Get<T>(PropertyInfo propertyInfo)
{
    var targetType = propertyInfo.DeclaringType;

    var getMethod = propertyInfo.GetGetMethod();

    var target = Expression.Parameter(targetType, "t");

    var body = Expression.Convert(
      Expression.Call(target, getMethod), typeof(object));

    return Expression.Lambda<Func<T, object>>(body, target).Compile();
}


那么问题来了,手动构建lambda表达式和上述直接通过创建托方式,哪种方式更佳呢?


单从代码量上和所给例子来看,理论上是利用创建委托方式更佳,但是其潜在的问题是,通过创建委托,我们必须遍历实体所有属性,那么像上述利用lambda表达式难道就不用了?


事实上,完全不用,手动构建lambda的好处在于,我们可手动构建实体所有属性,然后一次性赋值从而改善性能


至于如何一次性获取对应实体所有属性,然后手动构建lambda并赋值,这才是EntityFramework Core的妙处设计所在,后续文章我会详细给出


手动构建lambda的场景很多,再比如构建自动化脚本,对lambda使用到炉火纯青地步,那么自身整体核心竞争力将更上一台阶


 是的,我的文章都是建立在基础上的一点额外探索,比如微服务、k8s等等流行的玩意当前还完全没有涉及,一来实际项目中,还未应用,二是,不愿浅尝辄止,意义不大。万变不离其宗,所有我们看过的代码难道不都是语法组合吗?

本文分享自微信公众号 - dotNET跨平台(opendotnet)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

.Net Core3.1 配置Pomelo.EntityFrameworkCore.MySql数据操作(2)

.Net Core3.1 配置Pomelo.EntityFrameworkCore.MySql数据操作(2)

引入Pomelo.EntityFrameworkCore.MySql程序包

ConfigureServices

// other service configurations go here
            // replace "YourDbContext" with the class name of your DbContext
            services.AddDbContextPool<DbModel>(options => options
                // replace with your connection string
                .UseMySql("Server=localhost;Database=test;User=root;Password=woshishui;", mySqlOptions => mySqlOptions
                    // replace with your Server Version and Type
                    .ServerVersion(new ServerVersion(new Version(8, 0, 19), ServerType.MySql))
                ));

appsettings.json

{

  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;database=test;uid=root;pwd=woshishui;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}



创建Models实体类

alltestitem

using System.ComponentModel.DataAnnotations;

namespace BackStageCore3.Models
{
    public class alltestitem
    {
        // <summary>
        /// 机型
        /// </summary>
        [Key]
        public string 机型 { get; set; }

        /// <summary>
        /// 测试项目
        /// </summary>
        public string 测试项目 { get; set; }
        /// <summary>
        /// 耳机指令
        /// </summary>
        public string 耳机指令 { get; set; }
        /// <summary>
        /// 数值上限
        /// </summary>
        public string 数值上限 { get; set; }
        /// <summary>
        /// 数值下限
        /// </summary>
        public string 数值下限 { get; set; }
        /// <summary>
        /// 编号
        /// </summary>
        public int 编号 { get; set; }

    }
}

Controllers

AlltestitemController.cs

using BackStageCore3.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BackStageCore3.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class AlltestitemController : ControllerBase
    {
        private readonly DbModel _coreDbContext;

        public AlltestitemController(DbModel coreDbContext)
        {
            _coreDbContext = coreDbContext;
        }


        /// <summary>
        /// 查询所有
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult<IEnumerable<alltestitem>>> Get()
        {
            return await _coreDbContext.Alltestitem.ToListAsync();
        }

        /// <summary>
        /// 查询type类型下的内容
        /// </summary>
        /// <param name="id">条件</param>
        /// <returns>返回text</returns>
        [HttpGet("{id}", Name = "Getgj")]
        public List<alltestitem> Get(string id)
        {
            return _coreDbContext.Set<alltestitem>().Where(b => b.机型 == id).ToList();
        }


        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        // POST: api/Gj
        [HttpPost]
        public async Task<ActionResult<alltestitem>> Post(alltestitem gjs)
        {
            _coreDbContext.Alltestitem.Add(gjs);
            await _coreDbContext.SaveChangesAsync();
            //CreatedAtAction(actionName,routeValues,value).
            return CreatedAtAction(nameof(Get), new { id = gjs.机型 }, gjs);
        }


        /// <summary>
        /// 按条件更新数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        // PUT: api/Gj/5
        [HttpPut("{id}")]
        public async Task<IActionResult> Put(string id, alltestitem item)
        {
            if (id != item.机型)
            {
                return BadRequest();
            }
            _coreDbContext.Entry(item).State = EntityState.Modified;
            await _coreDbContext.SaveChangesAsync();

            return NoContent();
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // DELETE: api/ApiWithActions/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> Delete(int id)
        {
            var todoItem = await _coreDbContext.Alltestitem.FindAsync(id);
            if (todoItem == null)
            {
                return NotFound();
            }
            _coreDbContext.Alltestitem.Remove(todoItem);
            await _coreDbContext.SaveChangesAsync();
            return NoContent();
        }
    }
}

.NetCore 技术研究 - EntityFramework Core 3.0 Preview

.NetCore 技术研究 - EntityFramework Core 3.0 Preview

前段时间.Net Core 3.0 发布了,Entity Framework Core 3.0 也发布了 Preview 版。假期用了一上午大致研究了一遍,同时又体验了一把 Visual Studio 2019。总结一下分享给大家:

  1. VS2019 新建.Net Core 3.0 Console 应用,添加 EFCore 相关的 Nuget 引用
  2. 增加 appSettings.json 配置文件,配置数据库连接
  3. 新建 OneToMany 模型,使用 EF Core 完成数据库操作

一、VS2019 新建.Net Core 3.0 Console 应用,添加 EFCore 相关的 Nuget 引用

   1. 新建.Net Core 控制台应用 EFCoreTest

    

   

   新建完成后,查看项目的依赖性,我们可以看到:

   

  2. 添加 Microsoft.EntityFrameworkCore 3.0 Preview 版 Nuget 引用

   

   同时添加 Microsoft.EntityFrameworkCore.SqlServer3.0 Nuget 引用(我们要用到 SQL Server)

   

   这样我们就完成了项目的初始化。

二、增加 appsettings.json 配置文件,配置数据库连接

  1. 项目中添加 appsettings.json 文件

   配置文件的内容如下:

{"ConnectionStrings": {"BizDatabase": "Server=127.0.0.1;Database=master;User id=sa;password=******" }}

 2. 访问这个 appsettings.json 配置文件我们需要引用以下 Nuget 包:版本用的都是:3.0.0-preview3.19153.1

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Json

三、新建 OneToMany 模型,使用 EF Core 完成数据库操作

  这里以充电站和集控为例,1:M 的关联关系。

  这里我们同时使用了 EF 的注解,示例了个性化数据库表结构。以及外键关系

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;

namespace EFCoreTest
{
    /// <summary>
    /// 充电站
    /// </summary>
    [Table("Stations")]    
    public class ChargeStation
    {
        [Key]
        [Column("ID")]
        public string ID { get; set; }

        [Required]
        [Column("Code")]
        public string Code { get; set; }

        [Required]
        [Column("Name")]
        public string Name { get; set; }

        [Required]
        [Column("MaintainTel")]
        public long MaintainTel { get; set; }

        [ForeignKey("StationID")]        
        public virtual List<ChargeStationController> Controllers { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;

namespace EFCoreTest
{
    /// <summary>
    /// 电站集控
    /// </summary>
    [Table("StationCtrl")]
    public class ChargeStationController
    {
        [Key]
        [Column("ID")]        
        public string ID { get; set; }

        [Required]
        [Column("Code")]
        public string Code { get; set; }

        [Required]
        [Column("ControlAddress")]
        public string ControlAddress { get; set; }

        [Required]        
        [Column("StationID")]
        [ForeignKey("StationID")]
        public string StationID { get; set; }
    }
}

  实体及关联关系搞定后,我们介绍今天的主角  DbContext 的实现:ChargeDbContext

  ChargeDbContext 有几个重要的属性和方法:

public DbSet<ChargeStation> Stations { get; set; }
public DbSet<ChargeStationController> StationCtrl { get; set; }

重载 OnConfiguring 方法,加载配置系统、数据库连接串

public class ChargeDbContext : DbContext 
    {
        public DbSet<ChargeStation> Stations { get; set; }
        public DbSet<ChargeStationController> StationCtrl { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var builder = new ConfigurationBuilder()
           .SetBasePath(Directory.GetCurrentDirectory())
           .AddJsonFile("appsettings.json");

            var configuration = builder.Build();
        
            var conn = configuration.GetConnectionString("BizDatabase");
            optionsBuilder.UseSqlServer(conn);
        }
    }

 至此, 核心主要的 EFCore 代码已经完成,我们继续来实现对 ChargeStation 的数据库操作:

 我们在 Main 函数中实现对 ChargeStation 和 ChargeStationController 的删除和保存操作,以下代码,大家用过 EF 应该很熟悉:

class Program
    {
        static void Main(string[] args)
        {
            using (var context = new ChargeDbContext())
            {                
                foreach (var sta in context.Stations.Include(i => i.Controllers))
                {
                    context.Remove(sta);
                }
               
                context.SaveChanges();

                var station = new ChargeStation
                {
                    ID = "Station0001",
                    Code = "Station0001",
                    Name = "济南市奥体中路汉庭充电站",
                    MaintainTel = 13799990001,
                    Controllers = new System.Collections.Generic.List<ChargeStationController>
                    {
                         new ChargeStationController
                         {
                              ID = "Station0001-101",
                              Code =  "Station0001-101",
                              ControlAddress = "123456789",
                              StationID = "Station0001"
                         }
                    }
                };

                context.Stations.Add(station);
                context.SaveChanges();
                Console.WriteLine("Press any key!");
                Console.ReadKey();
            }
        }
    }

 以上即是 EntityFramework Core 3.0 Preview 体验和使用分享,后续有会有一篇文章介绍在 Debug 时,如何 Trace SQL 语句。

 

周国庆

2019/4/6

 

  

原文出处:https://www.cnblogs.com/tianqing/p/10661571.html

.NetCore技术研究-EntityFramework Core 3.0 Preview

.NetCore技术研究-EntityFramework Core 3.0 Preview

前段时间.Net Core 3.0 发布了,Entity Framework Core 3.0 也发布了Preview版。假期用了一上午大致研究了一遍,同时又体验了一把Visual Studio 2019。总结一下分享给大家:

  1. VS2019 新建.Net Core 3.0 Console应用,添加EFCore相关的Nuget引用
  2. 增加appSettings.json配置文件,配置数据库连接
  3. 新建OnetoMany模型,使用EF Core完成数据库操作

一、VS2019 新建.Net Core 3.0 Console应用,添加EFCore相关的Nuget引用

   1. 新建.Net Core控制台应用 EFCoreTest

    

   

   新建完成后,查看项目的依赖性,我们可以看到:

   

  2. 添加Microsoft.EntityFrameworkCore 3.0 Preview版 Nuget引用

   

   同时添加Microsoft.EntityFrameworkCore.sqlServer3.0 Nuget引用(我们要用到sql Server)

   

   这样我们就完成了项目的初始化。

二、增加appsettings.json配置文件,配置数据库连接

  1. 项目中添加appsettings.json文件

   配置文件的内容如下:

{"ConnectionStrings": {"BizDatabase": "Server=127.0.0.1;Database=master;User id=sa;password=******" }}

 2. 访问这个appsettings.json配置文件我们需要引用以下Nuget包:版本用的都是:3.0.0-preview3.19153.1

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Json

三、新建OnetoMany模型,使用EF Core完成数据库操作

  这里以充电站和集控为例,1:M的关联关系。

  这里我们同时使用了EF的注解,示例了个性化数据库表结构。以及外键关系

using System;
 System.Collections.Generic;
 System.ComponentModel.DataAnnotations;
 System.ComponentModel.DataAnnotations.Schema;
 System.Text;

namespace EFCoreTest
{
    /// <summary>
    /// 充电站
    </summary>
    [Table("Stations")]    
    public class ChargeStation
    {
        [Key]
        [Column("ID)]
        string ID { get; set; }

        [required]
        [Column(Codestring Code { Namestring Name { MaintainTellong MaintainTel { ; }

        [ForeignKey(StationID")]        
        virtual List<ChargeStationController> Controllers { ; }
    }
}
 电站集控
    StationCtrl)]
     ChargeStationController
    {
        [Key]
        [Column()]        
        ControlAddressstring ControlAddress { ; }

        [required]        
        [Column()]
        [ForeignKey(string StationID { ; }
    }
}

  实体及关联关系搞定后,我们介绍今天的主角  DbContext的实现:ChargeDbContext

  ChargeDbContext 有几个重要的属性和方法:

public DbSet<ChargeStation> Stations { get; set; }
public DbSet<ChargeStationController> StationCtrl { get; set; }

重载OnConfiguring方法,加载配置系统、数据库连接串

  ChargeDbContext : DbContext 
    {
        public DbSet<ChargeStation> Stations { ; }
        public DbSet<ChargeStationController> StationCtrl { ; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var builder = new ConfigurationBuilder()
           .SetBasePath(Directory.GetCurrentDirectory())
           .AddJsonFile(appsettings.json);

            var configuration = builder.Build();
        
            var conn = configuration.GetConnectionString(BizDatabase);
            optionsBuilder.UsesqlServer(conn);
        }
    }

 至此, 核心主要的EFCore 代码已经完成,我们继续来实现对ChargeStation的数据库操作:

 我们在Main函数中实现对ChargeStation和ChargeStationController的删除和保存操作,以下代码,大家用过EF应该很熟悉:

  Program
    {
        static void Main(string[] args)
        {
            using (var context =  ChargeDbContext())
            {                
                foreach (var sta in context.Stations.Include(i => i.Controllers))
                {
                    context.Remove(sta);
                }
               
                context.SaveChanges();

                var station =  ChargeStation
                {
                    ID = Station0001,Code = 济南市奥体中路汉庭充电站13799990001new System.Collections.Generic.List<ChargeStationController>
                    {
                          ChargeStationController
                         {
                              ID = Station0001-101= 123456789
                         }
                    }
                };

                context.Stations.Add(station);
                context.SaveChanges();
                Console.WriteLine(Press any key!);
                Console.ReadKey();
            }
        }
    }

 以上即是EntityFramework Core 3.0 Preview 体验和使用分享,后续有会有一篇文章介绍在Debug时,如何Trace sql语句。

 

周国庆

2019/05

 

  

总结

以上是小编为你收集整理的.NetCore技术研究-EntityFramework Core 3.0 Preview全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

Asp.Net Core 项目 EntityFramework Core 根据登录用户名过滤数据

Asp.Net Core 项目 EntityFramework Core 根据登录用户名过滤数据

 1、创建ASP.NET Core Web Applicatoin (MVC)项目,并且使用 Individual User Account

 

 

 

 2、创建数据筛选接口 Models->IDataFilter.cs

public interface IDataFilter
    {
        string UserName { get; set; }
    }

3、创建实体 Models->Book.cs 并继承 IDataFilter接口,并将实体加入到 Data->ApplicatoinDbContext.cs 上下文中.

public class Book : IDataFilter
    {
        public int Id { get; set; }
        [Display(Name = "书名")]
        public string Name { get; set; }
        public string UserName { get; set; }
    }
public class ApplicationDbContext : IdentityDbContext
    {
        public DbSet<Book> Books { get; set; }
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
    }

4、利用模板创建Book类的 CRUD界面。在 Controllers文件夹上 右键 选择 Add(新增)->Controller(控制器)

 

  

5、自动生成Book的增删改查之后,我们在这里要做一个细微的修改,因为我们IDataFilter字段 UserName是系统生成的,所以我们要修改两个地方

  将BooksController.cs 下的 Create Action(由于只做演示,没有去修改Update页面)里面的 Bind UserName去掉。修改后结果如下

   并将创建页面 Views->Books->Create.cshtml 中的 UserName 部份备注

  

 

  在母版页添加Book菜单链接 Views->Shared->_Layout.cshtml

6、打开Nuget管理控制台 迁移数据库,并F5运行,点击Book链接。检查一下程序 有没问题。

Add-Migration Init //创建迁移文件
Update-Database //更新到数据库

7、由于Book实体实现了IDataFilter,UserName我们会通过重写ApplicationDbContext的SaveChanges的实现,进行自动填充用户名.由于要获取登录信息,在ApplicationDbContext中我们需注入 IHttpContextAccessor

 

public class ApplicationDbContext : IdentityDbContext
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        public DbSet<Book> Books { get; set; }
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor)
            : base(options)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public override int SaveChanges()
        {
            FillDataFilterInfo();
            return base.SaveChanges();
        }
        public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            FillDataFilterInfo();
            return base.SaveChangesAsync(cancellationToken);
        }
        protected void FillDataFilterInfo() =>
            ChangeTracker
            .Entries()
            .Where(w => w.Entity is IDataFilter && w.State == EntityState.Added)
            .ToList()
            .ForEach(entry => ((IDataFilter)entry.Entity).UserName = CurrentUserName);

        private string CurrentUserName => _httpContextAccessor.HttpContext.User?.Identity?.Name;
    }

8、验证结果,运行项目,首先注册一个帐号。然后进行创建一本书。最终结果。

9、最后我们来实现数据过滤部份代码,打开 ApplicatonDbContex.cs

  添加私有方法DataFilters

private void DataFilters<T>(ModelBuilder builder)
            where T : class
        {
            builder.Entity<T>().HasQueryFilter(s => ((IDataFilter)s).UserName == CurrentUserName);
        }

  添加一个静态MethodInfo方法。这里用到返射实现

private static readonly MethodInfo _dataFiltersMethodInfo = typeof(ApplicationDbContext).GetMethod(nameof(DataFilters), BindingFlags.Instance | BindingFlags.NonPublic);

 

  在重写OnModelCreating ,针对所有实现 IDataFilter的实体添加数据过滤

  

protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Model
                .GetEntityTypes()
                .Where(w => typeof(IDataFilter).IsAssignableFrom(w.ClrType))
                .ToList().ForEach(entityType =>
                {
                    _dataFiltersMethodInfo
                      .MakeGenericMethod(entityType.ClrType)
                      .Invoke(this, new object[] { builder });
                });
            base.OnModelCreating(builder);
        }

10、运行程序,分别用不同的浏览器。注册两个帐号。然后创建几本书。最终结果

 

 

 

完结!第一次写,见谅。

源码地址:https://github.com/CC1027CC/DataFilter

 

原文出处:https://www.cnblogs.com/cc1027cc/p/11098437.html

今天关于EntityFramework Core查询数据基本本质3. 查询中的数据源有哪些的分享就到这里,希望大家有所收获,若想了解更多关于.Net Core3.1 配置Pomelo.EntityFrameworkCore.MySql数据操作(2)、.NetCore 技术研究 - EntityFramework Core 3.0 Preview、.NetCore技术研究-EntityFramework Core 3.0 Preview、Asp.Net Core 项目 EntityFramework Core 根据登录用户名过滤数据等相关知识,可以在本站进行查询。

本文标签:

上一篇Docker 查看应用的实际内存(docker查看内存占用)

下一篇在 Windows 上安装 Docker(在windows上安装docker)