C#使用mapper将DataReader映射到对象

时间:2016-01-12 23:45:49

标签: c# sqlite automapper

我一直在努力让ExpressMapper从DataReader映射到对象(基本上是Sqlite Rows - > Objects)。我已经在AutoMapper上取得了成功,但发现了其他一些问题让我找到了另一个地图工具。

在AutoMapper中我使用了以下代码,但在ExpressMapper中,所有字符串属性都是NULL,而长prop则始终为0,这表示映射失败。试图查看ExpressMapper的一些示例,但没有找到任何示例。你能帮我吗? 另外,除了AutoMapper(可能还有ExpressMapper)之外还有其他任何映射器可以帮助我实现这种情况吗?

谢谢!

 public class ImportedFiles
{
    public Int64 Id { get; set; }
    public String FileName { get; set; }
    public String Hash { get; set; }

    public ImportedFiles()
    {

    }

}

private static void ReadImportedFiles()
    {
        var lst = ReadData<ImportedFiles>("SELECT * FROM ImportedFiles").ToList();
    }

 public static IEnumerable<T> ReadData<T>(string queryString)
        {
            using (var connection = new SQLiteConnection(ConnectionBuilder.ConnectionString))
            {
                connection.Open();
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = queryString;
                    using (var reader = cmd.ExecuteReader())
                        if (reader.HasRows)
                            while (reader.Read())
                                yield return Mapper.Map<IDataRecord, T>(reader);
                }
            }
        }

2 个答案:

答案 0 :(得分:0)

  

除了AutoMapper(可能还有ExpressMapper)之外还有其他任何映射器可以帮助我实现这种情况吗?

是。通常,它们被称为对象关系映射器(缩写为O / RM或只是ORM)。有许多; .NET框架中最流行的几个是Entity FrameworkNHibernate

我认为您正在使用错误的工具(对象到对象映射器)来完成手头的任务(object-relational mapping)。

对象到对象映射器设计用于在紧密对齐的,强类型的,包含数据的类之间进行映射,通常用于保存手写映射代码。它们不是用于映射到更多通用数据容器(如DataRow),也不是用于处理在使用关系数据库时发挥作用的其他“管道”问题。

答案 1 :(得分:0)

ExpressMapper能够映射到DataRow。 这应该可以解决您的问题。

只需重构代码即可使用DataRow。并预先注册映射。

所以,如果你写:

yield return Mapper.Map<DataRow, T>(row);

按照我的建议进行映射(每次应用一次):

        Mapper.Register<DataRow, ImportedFiles>()
            .Member(dest => dest.Id,
                    src => DBNull.Value == src["Id"] ? 0 : (double)src["Id"])
            .Member(dest => dest.FileName,
                    src => DBNull.Value == src["FileName"] ? String.Empty : (string)src["FileName"])
            .Member(dest => dest.Hash,
                    src => DBNull.Value == src["Hash"] ? String.Empty : (string)src["Hash"])
            ;

你可以使用它。

[被修改]

如果您需要映射多个源(即:多个DataTable),那么您可以编写一个DataRowAdapter来区分您的映射,让我们知道ExpressMapper(或者您想要使用的任何ORM - 这适用于所有ORM)您的DataRow中需要哪些数据。

下面是您的代码的工作示例。

yield return Mapper.Map<DataRowAdapter<T>, T>(new DataRowAdapter<T>(row));

DataRowAdapter类:

public class DataRowAdapter<T>
{
    DataRow _dataRow;

    public DataRowAdapter(DataRow dataRow)
    {
        _dataRow = dataRow;
    }

    public DataRow Current
    {
        get
        {
            return _dataRow;
        }
    }
}

您的新品牌制图:

     Mapper.Register<DataRowAdapter<ImportedFiles>, ImportedFiles>()
        .Member(dest => dest.Id,
                src => DBNull.Value == src.Current["Id"] ? 0 : (double)src.Current["Id"])
        .Member(dest => dest.FileName,
                src => DBNull.Value == src.Current["FileName"] ? String.Empty : (string)src.Current["FileName"])
        .Member(dest => dest.Hash,
                src => DBNull.Value == src.Current["Hash"] ? String.Empty : (string)src.Current["Hash"])
        ;

完成。