C# 如何从数据库中动态设置值
我的搜索查询总是返回一行并将其放入数据表中 有没有办法检查列名和属性名是否匹配,然后设置值 例如:C# 如何从数据库中动态设置值,c#,C#,我的搜索查询总是返回一行并将其放入数据表中 有没有办法检查列名和属性名是否匹配,然后设置值 例如: SELECT * FROM mytable WHERE ID = 10; 查询返回列名:“ID、ScriptName、类型、标志、VerifiedBuild”及其值 然后运行foreach语句,检查列名和属性名是否匹配,并在下面设置属性值 public int ID { get; set; } public int ScriptName { get; set; }
SELECT * FROM mytable WHERE ID = 10;
查询返回列名:“ID、ScriptName、类型、标志、VerifiedBuild”及其值
然后运行foreach语句,检查列名和属性名是否匹配,并在下面设置属性值
public int ID { get; set; }
public int ScriptName { get; set; }
public int Type { get; set; }
public int Flags { get; set; }
public int VerifiedBuild { get; set; }
对。你需要使用反射。通过使用反射,可以获得数组中的参数名,并可以比较for循环中的名称
您可以非常轻松地使用EntityLite从数据读取器中具体化实体。这种功能被公开揭露了 假设你有一个如下的方法
public IDataReader GetDataReaderFromQuery()
{
//TODO: implement this method
throw new NotImplementedException();
}
和一个POCO实体:
public class MyEntity
{
// properties go here
}
您可以在datareader上使用FirstOrdFault、ToEnumberable和ToList扩展方法来获取POCO实体:
using inercya.EntityLite;
using inercya.EntityLite.Extensions;
//......
MyEntity SomeMethod()
{
using (reader = GetDataReaderFromQuery())
{
return reader.FirstOrDefault<MyEntity>();
}
}
使用inercya.EntityLite;
使用inercya.EntityLite.Extensions;
//......
MyEntity方法()
{
使用(reader=GetDataReaderFromQuery())
{
返回reader.FirstOrDefault();
}
}
EntityLite将在运行时使用从特定datareader具体化该类型实体的方法构建一个方法。该方法是缓存的,因此如果需要从具有相同模式的DataReader中具体化更多该类型的实体,则该方法将被重用。它几乎与反最佳手写代码一样快。借助(一个帮助您高效创建对象和访问编译时未知类型属性的小型库),您可以编写以下数据读取器扩展方法:
using FastDynamic;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sample
{
public static class DataReaderExtensions
{
private static void SetPropertiesFromDataReader(IDataReader reader, object entity)
{
if (reader == null || entity == null) throw new ArgumentNullException();
Type entityType = entity.GetType();
var setters = entityType.GetSetters();
for (int fieldIndex = 0; fieldIndex < reader.FieldCount; fieldIndex++)
{
var fieldName = reader.GetName(fieldIndex);
Setter setter = null;
if (!string.IsNullOrEmpty(fieldName) && setters.TryGetValue(fieldName, out setter))
{
if (!reader.IsDBNull(fieldIndex))
{
setter(entity, reader.GetValue(i));
}
}
}
}
public static IEnumerable<T> ToEnumberable<T>(this IDataReader reader) where T:class, new()
{
Type entityType = typeof(T);
Func<object> activator = entityType.GetActivator();
while (reader.Read())
{
var entity = activator();
SetPropertiesFromDataReader(reader, entity);
yield return (T)entity;
}
}
public T FirstOrDefault<T>(this IDataReader reader) where T : class, new()
{
return reader.ToEnumberable<T>().FirstOrDefault();
}
public List<T> ToList<T>(this IDataReader reader) where T : class, new()
{
return reader.ToEnumberable<T>().ToList();
}
}
}
使用FastDynamic;
使用制度;
使用System.Collections.Generic;
使用系统数据;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间示例
{
公共静态类DataReaderExtensions
{
私有静态void SetPropertiesFromDataReader(IDataReader读取器,对象实体)
{
如果(reader==null | | entity==null)抛出新的ArgumentNullException();
类型entityType=entity.GetType();
var setters=entityType.GetSetters();
对于(int fieldIndex=0;fieldIndex
这可能是一个很大的步骤,但您可能想看看ORM,例如,专门用于做这类事情的ORM(除此之外还有很多)。除了使用ORM之外,您当然可以手动完成,但如果您随后公布从数据库中获取值的准确程度,这将是一件好事(因为准确的实现将定义手动执行所需的步骤)同意@JamesThorpe,节省您自己的时间并迁移到实体框架。我将查看实体框架,谢谢。作为一名经验丰富的DBA和SQL Server开发人员,我不得不建议不要使用实体框架。您将失去对所执行SQL的控制,并且您的应用程序将遭受巨大的性能下降(投反对票的人没有给出)如果你发布的答案会修改代码部分或导致使用某些代码,请务必给出代码的示例(这样你的答案被接受的几率更高,投反对票的几率也更小)