如何从数据库中动态设置值

时间:2015-05-07 08:55:30

标签: c#

我的搜索查询将始终返回一行并将其放入数据表中。

有没有办法可以检查列名和属性名是否匹配,然后设置值?

例如:

    SELECT * FROM mytable WHERE ID = 10;

查询返回列名:“ID,ScriptName,Type,Flags,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; }

3 个答案:

答案 0 :(得分:0)

您可以使用EntityLite轻松完成,其核心是,EntityLite可以实现数据读取器中的实体。这种功能性公开暴露。

想象一下,你有一个像下面这样的方法;

public IDataReader GetDataReaderFromQuery()
{
    //TODO: implement this method
    throw new NotImplementedException();
}

一个POCO实体:

public class MyEntity 
{
    // properties go here
}

您可以在datareader上使用FisrtOrDefault,ToEnumberable和ToList扩展方法来获取POCO实体:

using inercya.EntityLite;
using inercya.EntityLite.Extensions;

//......

MyEntity SomeMethod()
{
    using (reader = GetDataReaderFromQuery())
    {

         return reader.FirstOrDefault<MyEntity>();
    }
}

EntityLite将在运行时使用DynamicMethod构建一个方法,该方法从该特定的datareader实现该类型的实体。该方法被缓存,因此如果您需要从具有相同模式的数据引用器实现该类型的更多实体,则该方法将被重用。它几乎和最好的手写代码一样快。

答案 1 :(得分:0)

FastDynamic(一个帮助您有效创建对象和访问编译时unkonwn类型的属性的小型库)的帮助下,您可以编写以下数据读取器扩展方法:

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();
        }

    }
}

答案 2 :(得分:-1)

是。你需要使用反射。通过使用反射,您可以在数组中获取参数名称,并且可以比较for循环中的名称。

ParameterInfo