我正在嘗試創建一個函式來通過原始查詢提取資料庫中特定記錄的值,并且我想回傳所請求物體型別的物件。
<(編輯:一些簡報以更好地理解目的)我正在制作一種物體框架插件函式,以便能夠在由代碼優先方法創建的 MySqlite 資料庫上請求和保存相應模型類的任何物件. 這是請求,但保存基本相同。對于所有物體,只有一種用于保存的功能和一種用于讀取的功能。這也將省去我為每個模型創建表單的麻煩,因為只有在前端處理所有模型的表單。這是一個 WebAssembly 專案,為管理員提供可視化資料庫管理系統>
我正在為注釋行下的那一小段代碼尋找優雅的解決方案,否則我將不得不使用具有所有型別和相應 tryParse 值的開關。如果有人知道我很感激并希望這段代碼對某人有用。
見注釋行
public async Task<object> GetClassData(string entityName, int id=0)
{
var classes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == "MecanicoAppSqlite.Shared.Models");
Type genericClassType = classes.FirstOrDefault(x => x.Name.ToLower() == entityName.ToLower());
PropertyInfo[] newClassProperties = genericClassType.GetProperties();
var tempClass = System.Reflection.Assembly.GetAssembly(genericClassType).CreateInstance(genericClassType.ToString());
string query = $"SELECT * from {entityName} WHERE Id LIKE {id}";
try
{
using (var command = context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = query;
command.CommandType = CommandType.Text;
await context.Database.OpenConnectionAsync();
using (var reader = await command.ExecuteReaderAsync())
{
reader.Read();
int columnCount= reader.FieldCount;
for (int h = 0; h < columnCount; h )
{
string colName = reader.GetName(h);
PropertyInfo pinfo = newClassProperties.FirstOrDefault(x => x.Name.ToLower() == colName.ToLower());
Type tp = pinfo.GetType();
//This tp above is a Int32 or string or whatever. Related problem is in next line
var x = reader.IsDBNull(h) ? null : reader.GetFieldValueAsync<tp>(h).Result;
pinfo.SetValue(tempClass, x);
}
}
}
return StatusCode(200, tempClass); // Get all users
}
catch (Exception e)
{
return StatusCode(500, e);
}
}
uj5u.com熱心網友回復:
您真的應該使用 Dapper 或 Entity 框架之類的東西。但是回答你的問題,你可以使用MakeGenericMethod:
public async Task<object> GetClassData(string entityName, int id = 0)
{
var classes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == "MecanicoAppSqlite.Shared.Models");
Type genericClassType = classes.FirstOrDefault(x => x.Name.ToLower() == entityName.ToLower());
PropertyInfo[] newClassProperties = genericClassType.GetProperties();
var tempClass = System.Reflection.Assembly.GetAssembly(genericClassType).CreateInstance(genericClassType.ToString());
string query = $"SELECT * from {entityName} WHERE Id LIKE {id}";
try
{
using (var command = context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = query;
command.CommandType = CommandType.Text;
await context.Database.OpenConnectionAsync();
// Here we get the MethodInfo for the method we want to call
MethodInfo method = typeof(DbDataReaderExtensions).GetMethod("GetFieldValue");
using (var reader = await command.ExecuteReaderAsync())
{
reader.Read();
int columnCount = reader.FieldCount;
for (int h = 0; h < columnCount; h )
{
string colName = reader.GetName(h);
PropertyInfo pinfo = newClassProperties.FirstOrDefault(x => x.Name.ToLower() == colName.ToLower());
// pinfo.GetType() will give you typeof(PropertyInfo) not the type of the property
Type tp = pinfo.PropertyType;
var genericMethod = method.MakeGenericMethod(new[] { tp });
var x = reader.IsDBNull(h) ? null : genericMethod.Invoke(reader, new object[] {h});
pinfo.SetValue(tempClass, x);
}
}
}
return StatusCode(200, tempClass); // Get all users
}
catch (Exception e)
{
return StatusCode(500, e);
}
}
uj5u.com熱心網友回復:
我現在將使用帶有我在此應用程式中使用的所有資料型別的開關
using (var reader = await command.ExecuteReaderAsync())
{
reader.Read();
var tempClass = System.Reflection.Assembly.GetAssembly(genericClassType).CreateInstance(genericClassType.ToString());
int numeroDeColunas = reader.FieldCount;
for(int h=0;h<numeroDeColunas;h )
{
string colName = reader.GetName(h);
PropertyInfo property = newClassProperties.FirstOrDefault(x => x.Name.ToLower() == colName.ToLower());
Type propType = property.GetType();
var x = reader.IsDBNull(h) ? "" : reader.GetFieldValueAsync<string>(h).Result;
switch (propType.Name)
{
case "Int32":
int iv;
if (!Int32.TryParse(x, out iv)) throw new ApplicationException("Unable to parse at ValuesController>GetAll");
property.SetValue(tempClass, iv);
break;
case "String":
property.SetValue(tempClass, x);
break;
case "DateTime":
DateTime dv;
if (!DateTime.TryParse(x, out dv)) throw new ApplicationException("Unable to parse at ValuesController>GetAll");
property.SetValue(tempClass, dv);
break;
case "TimeSpan":
TimeSpan tv;
if (!TimeSpan.TryParse(x, out tv)) throw new ApplicationException("Unable to parse at ValuesController>GetAll");
property.SetValue(tempClass, tv);
break;
default:
Console.WriteLine("Subject is C#");
break;
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/403893.html
標籤:
上一篇:將四元數轉換回值?
