动态生成表达式树

var items = Query<Book>(new string[] { "Id", "PubTime", "Title" });
foreach (object[] row in items)
{
    long id = (long)row[0];
    DateTime pubTime = (DateTime)row[1];
    string title = (string)row[2];
    Console.WriteLine(id + "," + pubTime + "," + title);
}

IEnumerable<object[]> Query<TEntity>(string[] propNames) where TEntity : class
{
    ParameterExpression exParameter = Expression.Parameter(typeof(TEntity));
    List<Expression> exProps = new List<Expression>();
    foreach (string propName in propNames)
    {
        Expression exProp = Expression.Convert(Expression.MakeMemberAccess(
            exParameter, typeof(TEntity).GetProperty(propName)), typeof(object));
        exProps.Add(exProp);
    }
    Expression[] initializers = exProps.ToArray();
    NewArrayExpression newArrayExp = Expression.NewArrayInit(typeof(object), initializers);
    var selectExpression = Expression.Lambda<Func<TEntity, object[]>>(newArrayExp, exParameter);
    using MyDbcontext ctx = new MyDbcontext();
    IQueryable<object[]> selectQueryable = ctx.Set<TEntity>().Select(selectExpression);
    return selectQueryable.ToArray();
}
using ExpressionTreeDemon;
using System.Linq.Expressions;
using ExpressionTreeToString;
using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);
builder.Build().Run();
using MyDbcontext ctx = new MyDbcontext();

//var a1 = new Book
//{
//    Price = 10,
//    AuthorName = "唐1僧",
//    PubTime = new DateTime(2015, 10, 1),
//    Title = "西游1记"
//};

//ctx.Books.Add(a1);
//ctx.SaveChanges();

//var a1 = new Book
//{
//    Price = 50,
//    AuthorName = "唐1僧",
//    PubTime = new DateTime(2014, 10, 1),
//    Title = "西1游记"
//};

//var a2 = new Book
//{
//    Price = 50,
//    AuthorName = "西1门庆",
//    PubTime = new DateTime(2016, 10, 1),
//    Title = "水1浒传"
//};



//Console.WriteLine(ctx.Books.SingleOrDefault(a => a.Id == 1).Title);

//var b1 = new Book
//{
//    AuthorName = "杨中科",
//    Title = "零基础趣学C语言",
//    Price = 59.8,
//    PubTime = new DateTime(2019, 3, 1)
//};
//var b2 = new Book
//{
//    AuthorName = "Robert Sedgewick",
//    Title = "算法(第4版)",
//    Price = 99,
//    PubTime = new DateTime(2012, 10, 1)
//};
//var b3 = new Book
//{
//    AuthorName = "吴军",
//    Title = "数学之美",
//    Price = 69,
//    PubTime = new DateTime(2020, 5, 1)
//};
//var b4 = new Book
//{
//    AuthorName = "杨中科",
//    Title = "程序员的SQL金典",
//    Price = 52,
//    PubTime = new DateTime(2008, 9, 1)
//};
//var b5 = new Book
//{
//    AuthorName = "吴dd军",
//    Title = "文dd明之光",
//    Price = 246,
//    PubTime = new DateTime(2017, 3, 1)
//};
//ctx.Books.Add(b1);
//ctx.Books.Add(b2);
//ctx.Books.Add(b3);
//ctx.Books.Add(b4);
//ctx.Books.Add(b5);
//await ctx.SaveChangesAsync();
//var a1 = new Book
//{
//    Price = 50,
//    AuthorName = "唐僧",
//    PubTime = new DateTime(2015, 10, 1),
//    Title = "西游记"
//};

//var a2 = new Book
//{
//    Price = 500,
//    AuthorName = "西门庆",
//    PubTime = new DateTime(2016, 10, 1),
//    Title = "水浒传"
//};

//ctx.Books.Add(a1);
//ctx.Books.Add(a2);
//ctx.SaveChangesAsync();



//Func<Book, bool> f1 = b => b.Price > 5 || b.AuthorName.Contains("杨中科");
//Expression<Func<Book, bool>> e = b => b.Price > 5 || b.AuthorName.Contains("杨中科");
//Console.WriteLine(f1);
//Console.WriteLine(e);
//Expression<Func<Book, bool>> c = b => b.AuthorName.Contains("杨中科") || b.Price > 30;
//Console.WriteLine(c.ToString("Object notation", "C#"));

//动态创建和Expression<Func<Book, bool>> e = b =>b.Price > 5一样的代码

//ParameterExpression paramB = Expression.Parameter(typeof(Book), "b");
//MemberExpression exprLeft = Expression.MakeMemberAccess(paramB, typeof(Book).GetProperty("Price"));
//ConstantExpression exprRight = Expression.Constant(5.0, typeof(double));
//BinaryExpression exprBody = Expression.MakeBinary(ExpressionType.GreaterThan, exprLeft, exprRight);
//Expression<Func<Book, bool>> expr1 = Expression.Lambda<Func<Book, bool>>(exprBody, paramB);
//ctx.Books.Where(expr1).ToList();
//Console.WriteLine(expr1.ToString("Object notation", "C#"));


//5.3.8	不用Emit生成IL代码实现Select的动态化


//var items = Query<Book>(new string[] { "Id", "PubTime", "Title" });
//foreach (object[] row in items)
//{
//    long id = (long)row[0];
//    DateTime pubTime = (DateTime)row[1];
//    string title = (string)row[2];
//    Console.WriteLine(id + "," + pubTime + "," + title);
//}

//IEnumerable<object[]> Query<TEntity>(string[] propNames) where TEntity : class
//{
//    ParameterExpression exParameter = Expression.Parameter(typeof(TEntity));
//    List<Expression> exProps = new List<Expression>();
//    foreach (string propName in propNames)
//    {
//        Expression exProp = Expression.Convert(Expression.MakeMemberAccess(
//            exParameter, typeof(TEntity).GetProperty(propName)), typeof(object));
//        exProps.Add(exProp);
//    }
//    Expression[] initializers = exProps.ToArray();
//    NewArrayExpression newArrayExp = Expression.NewArrayInit(typeof(object), initializers);
//    var selectExpression = Expression.Lambda<Func<TEntity, object[]>>(newArrayExp, exParameter);
//    using MyDbcontext ctx = new MyDbcontext();
//    IQueryable<object[]> selectQueryable = ctx.Set<TEntity>().Select(selectExpression);
//    return selectQueryable.ToArray();
//}


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

	<ItemGroup>
		<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.3">
		  <PrivateAssets>all</PrivateAssets>
		  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
		</PackageReference>
		<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3">
			<PrivateAssets>all</PrivateAssets>
			<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
		</PackageReference>
		<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
		<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
		<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
		<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
		<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
		<PackageReference Include="NModbus4.NetCore" Version="2.0.1" />
		<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1" />
		<PackageReference Include="ExpressionTreeToString" Version="3.4.65" />
	</ItemGroup>

	<ItemGroup>
	  <None Update="MyNode.json">
	    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  </None>
	</ItemGroup>

</Project>

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExpressionTreeDemon
{
    public class MyDbcontext:DbContext
    {
        //public MyDbcontext()
        //{

        //}
        //public MyDbcontext(DbContextOptions<MyDbcontext> options):base(options)
        //{

        //}
        private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
        
        public DbSet<Book> Books { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            cfgBuilder.AddJsonFile("MyNode.json", optional: true, reloadOnChange: true);
            IConfigurationRoot cfgRoot = cfgBuilder.Build();
            //string conn = cfgRoot.GetSection("ConnectionStrings:SqliteConnectionString").Value;
            string conn = cfgRoot.GetSection("ConnectionStrings:MySQLConnectionString").Value;
            optionsBuilder.UseMySql(conn, new MySqlServerVersion(new Version(5, 7, 35)));
            //optionsBuilder.UseMySql("server=192.168.207.107; database=MyBooks2; uid=root; pwd=123456;", new MySqlServerVersion(new Version(5, 7, 35)));
            //optionsBuilder.LogTo(Console.WriteLine);
            //optionsBuilder.UseSqlite(conn);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder); 
            modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
        }
    }
}

public class Book
{
    public long Id { get; set; }//主键
    public string? Title { get; set; }//标题
    public DateTime PubTime { get; set; }//发布日期
    public double Price { get; set; }//单价
    public string? AuthorName { get; set; }//作者名字
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

class BookEntityConfig : IEntityTypeConfiguration<Book>
{
    public void Configure(EntityTypeBuilder<Book> builder)
    {
        builder.ToTable("Book");
        builder.HasKey(x => x.Id);
        builder.Property(e => e.Title).HasMaxLength(50).IsRequired();
        builder.Property(e => e.AuthorName).HasMaxLength(20).IsRequired();
    }
}
{
  "ConnectionStrings": {
    "SqliteConnectionString": "Data Source=D:\\cSharpe\\code\\ExpressionTreeDemon\\ExpressionTreeDemon\\bin\\Debug\\net6.0\\Database\\DbSqlite.db",
    "MySQLConnectionString": "server=192.168.207.107; database=MyBooks2; uid=root; pwd=123456;"
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值