.NET在EF中使用sql,用动态类吧!

                   .NET在EF中使用sql,用动态类吧!

前言

    在.NET中使用Entity Framework能快速、方便地结合LINQ来对数据库进行一系列的增删改查操作。但是由于EF根据表达式最后生成通用的sql来执行,进行具体的数据库操作。根据本人使用EF的经验,对于增、删、改的操作,可以直接使用EF的接口进行快速开发。但是对于查询的操作,最好是使用EF调用sql来操作。

问题呈现

    在EF中调用sql进行数据查询后,需要返回一个指定类型的数据列表,那么这个类型是需要在调用的时候指定的。我们就会遇到这种问题:我只需要查一些简单的数据,例如查询一下符合某条件的数据数量等等,就必须新建一个类型,增加了程序的冗余度。

解决方案

    需要实现动态生成类的方法,可以插入属性名称和属性类型,返回一个类型,提供给EF使用。

实现

    

//该类是用于定义属性节点的,包括属性的名称、属性的类型。public class PropertyItem
    {
        public PropertyItem(string name, Type type)
        {
            this.Name = name;
            this.Type = type;
        }

        public string Name { set; get; }
        public Type Type { set; get; }
    }

     

//该类是提供接口,动态生成类型的。public class UserTypeFactory
    {
        public static Type GetUserType(params PropertyItem[] itemList)
        {
            TypeBuilder builder = CreateTypeBuilder(
                    "MyDynamicAssembly", "MyModule", "MyType");
            foreach(var item in itemList)
            {
                CreateAutoImplementedProperty(builder, item.Name, item.Type);
            }

            Type resultType = builder.CreateType();
            return resultType;
        }

        private static TypeBuilder CreateTypeBuilder(
            string assemblyName, string moduleName, string typeName)
        {
            TypeBuilder typeBuilder = AppDomain
                .CurrentDomain
                .DefineDynamicAssembly(new AssemblyName(assemblyName),
                                       AssemblyBuilderAccess.Run)
                .DefineDynamicModule(moduleName)
                .DefineType(typeName, TypeAttributes.Public);
            typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
            return typeBuilder;
        }

        private static void CreateAutoImplementedProperty(
            TypeBuilder builder, string propertyName, Type propertyType)
        {
            const string PrivateFieldPrefix = "m_";
            const string GetterPrefix = "get_";
            const string SetterPrefix = "set_";

            // 定义字段.
            FieldBuilder fieldBuilder = builder.DefineField(
                string.Concat(PrivateFieldPrefix, propertyName),
                              propertyType, FieldAttributes.Private);

            // 定义属性
            PropertyBuilder propertyBuilder = builder.DefineProperty(
                propertyName, System.Reflection.PropertyAttributes.HasDefault, propertyType, null);

            // 属性的getter和setter的特性
            MethodAttributes propertyMethodAttributes =
                MethodAttributes.Public | MethodAttributes.SpecialName |
                MethodAttributes.HideBySig;

            // 定义getter方法
            MethodBuilder getterMethod = builder.DefineMethod(
                string.Concat(GetterPrefix, propertyName),
                propertyMethodAttributes, propertyType, Type.EmptyTypes);

            ILGenerator getterILCode = getterMethod.GetILGenerator();
            getterILCode.Emit(OpCodes.Ldarg_0);
            getterILCode.Emit(OpCodes.Ldfld, fieldBuilder);
            getterILCode.Emit(OpCodes.Ret);

            // 定义setter方法
            MethodBuilder setterMethod = builder.DefineMethod(
                string.Concat(SetterPrefix, propertyName),
                propertyMethodAttributes, null, new Type[] { propertyType });

            ILGenerator setterILCode = setterMethod.GetILGenerator();
            setterILCode.Emit(OpCodes.Ldarg_0);
            setterILCode.Emit(OpCodes.Ldarg_1);
            setterILCode.Emit(OpCodes.Stfld, fieldBuilder);
            setterILCode.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(getterMethod);
            propertyBuilder.SetSetMethod(setterMethod);
        }

    }

使用

    

YmsEntities entities=new YmsEntities();dynamic studentDic= entities.Database.SqlQuery(UserTypeFactory.GetUserType(new PropertyItem("ID", typeof(int)), new PropertyItem("num", typeof(string))),"select ID ,Name as num from student");
foreach (var usercount in studentDic)
{  //业务
}
时间: 2024-10-15 10:03:49

.NET在EF中使用sql,用动态类吧!的相关文章

EF中使用SQL语句或存储过程

EF中使用SQL语句或存储过程或视图 1.无参数查询var model = db.Database.SqlQuery<UserInfo>("select* from UserInfoes ").ToList(); 2.有参查询var model = db.Database.SqlQuery<UserInfo>("select* from UserInfoes where [email protected] ",new SqlParameter

sqlserver 存储过程中拼接sql语句 动态执行

ALTER PROC [dbo].[Student_Friend_Get] @startRowIndexId INT, @maxNumberRows INT, @schoolId INT, @gradeId INT, @cId INT, @keyWords NVARCHAR(100), @userName VARCHAR(50) AS BEGIN DECLARE @sqlfilter VARCHAR(max) SET @sqlfilter = ' ' IF(@schoolId <> -1) S

EF中执行sql语句

EF原理 EF 会自动把 Where().OrderBy().Select()等这些编译成"表达式树(Expression Tree)",然后会把表达式树翻译成 SQL 语句去执行.(编译原理,AST)因此不是"把数据都取到内存中,然后使用集合的方法进行数据过滤",因此性能不会低.但是如果这个操作不能被翻译成 SQL 语句,则或者报错,或者被放到内存中操作,性能就会非常低 跟踪EF的查询Sql语句: DbContext 有一个 Database 属性,其中的 Log

在EF中执行SQL语句

你可能要问,我用EF不就为了避免写SQL吗?如果要写SQL我不如直接用ADO.NET得了.话虽然这么说没错,可有些时候使用EF操作数据还是有一些不方便,例如让你根据条件删除一组记录,如果按照正常的流程来走,你就得先把这些数据查出来,然后再一条一条地删除它们,这样不仅麻烦而且性能也比较低.这种情况下SQL就显示出它的威力了. 而使用EF执行SQL又比ADO.NET方便,特别是在执行查询语句的时候,EF会把查询到的数据自动保存到数据实体中,省去了使用DataReader的麻烦.同时查询出来的数据还会

在EF中使用SQL语句

在实体框架4.1和更高版本中,你可以直接执行任意数据源的命令.使用下面的方法,使您能够执行对数据源的原始的SQL命令 返回特定类型的实体,DbSet上的sqlquery使您能够执行原始的SQL查询返回特定的实体实例,默认情况,被返回的实体被tracked by The COntext ,可以通过在 SqlQuery上调用AsNoTracking来改变 using (var context = new SchoolEntities()) { var departments = context.De

EF 学习系列三 数据操作数据加载及EF中执行Sql

我们通过EF来对数据库进行操作并持久化到数据库,那么EF必然通过EF上下文来维护实体的状态,明确知道每一个状态所对应的操作.也就是说EF通过上下文负责跟踪实体的状态.EF实体状态存在命名空间System.Data.Entity下的EntityState枚举中 原文地址:https://www.cnblogs.com/jhgfdm/p/12274286.html

EF中使用SQL语句或存储过程(小笔记)

1.无参数查询 var model = db.Database.SqlQuery<UserInfo>("select* from UserInfoes ").ToList(); 2.有参查询 var model = db.Database.SqlQuery<UserInfo>("select* from UserInfoes where [email protected] ",new SqlParameter("@ID",

EF中Entity SQL用法

public List<policecase> GetPoliceCaseList(PoliceCaseFilter view)        {            string sqlString = "SELECT value pc FROM Entities.policecase AS pc";            var where = "";            if (!string.IsNullOrWhiteSpace(view.C

EF中使用SQL函数

SqlFunctions引用命名空间:using System.Data.Objects.SqlClient; db.Favorite.Where(_ => SqlFunctions.PatIndex(keyWord, _.ItemName) > 0 && _.UserId == itemId); 与 db.Favorite.Where(_ => _.ItemName.Contains(keyWord) && _.UserId == itemId); 类似