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的控制,并且您的应用程序将遭受巨大的性能下降(投反对票的人没有给出)如果你发布的答案会修改代码部分或导致使用某些代码,请务必给出代码的示例(这样你的答案被接受的几率更高,投反对票的几率也更小)