[SQL] SQL 쿼리 실행 엔티티 프레임 워크에서 익명 유형 결과
SQLSQL 쿼리 실행 엔티티 프레임 워크에서 익명 유형 결과
나는 .NET 프레임 워크 4.0 코드 첫 번째 방법으로 엔티티 프레임 워크 5.0을 사용하고 있습니다. 지금은 내가 따라 엔티티 프레임 워크에 원시 SQL을 실행할 수 있다는 것을 알고
var students = Context.Database.SqlQuery<Student>("select * from student").ToList();
그것은 완벽하게 작동하지만 내가 원하는 것은 익명의 결과를 돌려주고 있어요. 다음과 같은 예를 들어 나는 학생 테이블에서 특정 컬럼을 원하는
var students = Context.Database.SqlQuery<Student>("select FirstName from student").ToList();
그것은 작동하지 않습니다. 그것은 예외를 제공합니다
나는 동적 유형을 시도 그래서
var students = Context.Database.SqlQuery<dynamic>("select FirstName from student").ToList();
그것은 또한 빈 객체를 반환, 작동하지 않습니다. 그것은에서 사용할 수있는 데이터가 없습니다.
동적 SQL 쿼리에서 익명 형식의 결과를 얻을 수있는 방법이 있습니까?
해결법
-
==============================
1.당신은 그 원시 SQL을 사용해야 엔티티 프레임 워크 SQL 쿼리
알려진 유형의 개체에 대한 것입니다에만 작동합니다. 당신은 그 원시 SQL을 사용해야 엔티티 프레임 워크 SQL 쿼리
알려진 유형의 개체에 대한 것입니다에만 작동합니다. 여기에 방법 I 사용은 다음과 같습니다
public static IEnumerable<dynamic> DynamicListFromSql(this DbContext db, string Sql, Dictionary<string, object> Params) { using (var cmd = db.Database.Connection.CreateCommand()) { cmd.CommandText = Sql; if (cmd.Connection.State != ConnectionState.Open) { cmd.Connection.Open(); } foreach (KeyValuePair<string, object> p in Params) { DbParameter dbParameter = cmd.CreateParameter(); dbParameter.ParameterName = p.Key; dbParameter.Value = p.Value; cmd.Parameters.Add(dbParameter); } using (var dataReader = cmd.ExecuteReader()) { while (dataReader.Read()) { var row = new ExpandoObject() as IDictionary<string, object>; for (var fieldCount = 0; fieldCount < dataReader.FieldCount; fieldCount++) { row.Add(dataReader.GetName(fieldCount), dataReader[fieldCount]); } yield return row; } } } }
이처럼 호출 할 수 있습니다 :
List<dynamic> results = DynamicListFromSql(myDb,"select * from table where a=@a and b=@b", new Dictionary<string, object> { { "a", true }, { "b", false } }).ToList();
-
==============================
2.다음은 나를 위해 벌금을 일 최종 솔루션입니다.
다음은 나를 위해 벌금을 일 최종 솔루션입니다.
public static System.Collections.IEnumerable DynamicSqlQuery(this Database database, string sql, params object[] parameters) { TypeBuilder builder = createTypeBuilder( "MyDynamicAssembly", "MyDynamicModule", "MyDynamicType"); using (System.Data.IDbCommand command = database.Connection.CreateCommand()) { try { database.Connection.Open(); command.CommandText = sql; command.CommandTimeout = command.Connection.ConnectionTimeout; foreach (var param in parameters) { command.Parameters.Add(param); } using (System.Data.IDataReader reader = command.ExecuteReader()) { var schema = reader.GetSchemaTable(); foreach (System.Data.DataRow row in schema.Rows) { string name = (string)row["ColumnName"]; //var a=row.ItemArray.Select(d=>d.) Type type = (Type)row["DataType"]; if(type!=typeof(string) && (bool)row.ItemArray[schema.Columns.IndexOf("AllowDbNull")]) { type = typeof(Nullable<>).MakeGenericType(type); } createAutoImplementedProperty(builder, name, type); } } } finally { database.Connection.Close(); command.Parameters.Clear(); } } Type resultType = builder.CreateType(); return database.SqlQuery(resultType, sql, parameters); } 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_"; // Generate the field. FieldBuilder fieldBuilder = builder.DefineField( string.Concat(PrivateFieldPrefix, propertyName), propertyType, FieldAttributes.Private); // Generate the property PropertyBuilder propertyBuilder = builder.DefineProperty( propertyName, System.Reflection.PropertyAttributes.HasDefault, propertyType, null); // Property getter and setter attributes. MethodAttributes propertyMethodAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // Define the getter method. MethodBuilder getterMethod = builder.DefineMethod( string.Concat(GetterPrefix, propertyName), propertyMethodAttributes, propertyType, Type.EmptyTypes); // Emit the IL code. // ldarg.0 // ldfld,_field // ret ILGenerator getterILCode = getterMethod.GetILGenerator(); getterILCode.Emit(OpCodes.Ldarg_0); getterILCode.Emit(OpCodes.Ldfld, fieldBuilder); getterILCode.Emit(OpCodes.Ret); // Define the setter method. MethodBuilder setterMethod = builder.DefineMethod( string.Concat(SetterPrefix, propertyName), propertyMethodAttributes, null, new Type[] { propertyType }); // Emit the IL code. // ldarg.0 // ldarg.1 // stfld,_field // ret 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); }
-
==============================
3.당신은 여기에서 코드를 시도 아래로 스크롤 stankovski의 구현 찾을 수 있습니다 : http://www.codeproject.com/Articles/206416/Use-dynamic-type-in-Entity-Framework-SqlQuery
당신은 여기에서 코드를 시도 아래로 스크롤 stankovski의 구현 찾을 수 있습니다 : http://www.codeproject.com/Articles/206416/Use-dynamic-type-in-Entity-Framework-SqlQuery
정적 클래스에 코드를 복사 한 후, 당신은 당신이 원하는 것을 얻을이 함수를 호출 할 수 있습니다 :
var students = Context.Database.DynamicSqlQuery("select FirstName from student").ToList()
-
==============================
4.당신이 엔티티를 가지고 만하려는 경우 속성 중 일부는 반사의 도움으로 더 나은 솔루션을 얻을 수 있습니다 백업합니다.
당신이 엔티티를 가지고 만하려는 경우 속성 중 일부는 반사의 도움으로 더 나은 솔루션을 얻을 수 있습니다 백업합니다.
이 코드는 위의 답변에서와 동일한 샘플을 축적.
이 외에도 당신은 유형과 다시 싶어 필드의 배열을 지정할 수 있습니다.
그 결과 유형을 IEnumerable이다.
public static class DatabaseExtension { public static IEnumerable<T> DynamicSqlQuery<T>(this Database database, string[] fields, string sql, params object[] parameters) where T : new() { var type = typeof (T); var builder = CreateTypeBuilder("MyDynamicAssembly", "MyDynamicModule", "MyDynamicType"); foreach (var field in fields) { var prop = type.GetProperty(field); var propertyType = prop.PropertyType; CreateAutoImplementedProperty(builder, field, propertyType); } var resultType = builder.CreateType(); var items = database.SqlQuery(resultType, sql, parameters); foreach (object item in items) { var obj = new T(); var itemType = item.GetType(); foreach (var prop in itemType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) { var name = prop.Name; var value = prop.GetValue(item, null); type.GetProperty(name).SetValue(obj, value); } yield return obj; } } 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_"; // Generate the field. FieldBuilder fieldBuilder = builder.DefineField( string.Concat(privateFieldPrefix, propertyName), propertyType, FieldAttributes.Private); // Generate the property PropertyBuilder propertyBuilder = builder.DefineProperty( propertyName, PropertyAttributes.HasDefault, propertyType, null); // Property getter and setter attributes. MethodAttributes propertyMethodAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // Define the getter method. MethodBuilder getterMethod = builder.DefineMethod( string.Concat(getterPrefix, propertyName), propertyMethodAttributes, propertyType, Type.EmptyTypes); // Emit the IL code. // ldarg.0 // ldfld,_field // ret ILGenerator getterILCode = getterMethod.GetILGenerator(); getterILCode.Emit(OpCodes.Ldarg_0); getterILCode.Emit(OpCodes.Ldfld, fieldBuilder); getterILCode.Emit(OpCodes.Ret); // Define the setter method. MethodBuilder setterMethod = builder.DefineMethod( string.Concat(setterPrefix, propertyName), propertyMethodAttributes, null, new Type[] { propertyType }); // Emit the IL code. // ldarg.0 // ldarg.1 // stfld,_field // ret 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); } }
당신은 이런 식으로 호출 할 수 있습니다 :
var fields = new[]{ "Id", "FirstName", "LastName" }; var sql = string.Format("SELECT {0} FROM People WHERE Id = @id", string.Join(", ", fields)); var person = db.Database.DynamicSqlQuery<People>(fields, sql, new SqlParameter("id", id)) .FirstOrDefault();
사실 그것은 단순한 유형에서 작동 및 오류 처리가 없습니다.
-
==============================
5.나는 그런 식으로 그것을 사용
나는 그런 식으로 그것을 사용
ORMClass :
public class ORMBase<T, TContext> : IORM<T> where T : class where TContext : DbContext, IDisposable, new()
방법:
public IList<TResult> GetSqlQuery<TResult>(string sql, params object[] sqlParams) { using (TContext con = new TContext()) { return Enumerable.ToList(con.Database.SqlQuery<TResult>(sql, sqlParams)); } }
그리고 마지막으로 사용
public class ResimORM : ORMBase<Resim, mdlOgrenciKulup>, IDisposable { public void Dispose() { GC.SuppressFinalize(this); } } ResimORM RE_ORM = new ResimORM(); List<Resim> a = RE_ORM.GetSqlQuery<Resim>(sql,null).ToList(); int b = RE_ORM.GetSqlQuery<int>(sql,null).FirstOrDefault();
from https://stackoverflow.com/questions/26749429/anonymous-type-result-from-sql-query-execution-entity-framework by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 그것은 엔티티 프레임 워크와 네이티브 SQL을 실행할 수 있습니까? (0) | 2020.04.24 |
---|---|
[SQL] SQL 서버 자동으로 자릅니다의 VARCHAR는 저장 프로 시저의 (0) | 2020.04.24 |
[SQL] PostgreSQL의 버전 - 만 SQL을 사용하여 반환 사전 UPDATE 열 값 (0) | 2020.04.24 |
[SQL] MySQL의 "IN"쿼리의 질서를 유지 (0) | 2020.04.24 |
[SQL] 지난 몇 일 SELECT MYSQL? (0) | 2020.04.24 |