【问题标题】:How to map database table columns to class properties in Dapper .Net如何将数据库表列映射到 Dapper .Net 中的类属性
【发布时间】:2014-01-16 04:52:02
【问题描述】:

我有一个名为employee 的表,并且有几个列,如EmpID,FirstName,MiddleName,LastName,Address,EmailID,RegionID,DesgID,我正在使用 Dapper .Net 和扩展来处理 SQL Server 数据库。我使用 Dapper SqlExtensions 来插入、更新、删除功能,并使用 Dapper multimapper 选项来填充细节。所以我在上面的employee表中使用了下面的类

    [Table("employee")] //To map the table to class
    public class EmployeeModel
    {
        [Key] //Denote primary key
        public Int32 EmpID { get; set; }
        [Column("FirstName")] //Trying to map table column FirstName to variable First (Fails)
        public string First { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string EmailID { get; set; }
        public Int32 RegionID { get; set; }
        public RegionModel Region { get; set; }
        public DesignationModel Designation { get; set; }
        public Int32 DesgID { get; set; }

        public Int32 Add(EmployeeModel Details)
        {
            try
            {
                using (var connection = DBProviderFactory.GetOpenConnection()) //Creating IDbConnection Here
                {
                    return Convert.ToInt32(connection.Insert(Details)); //Using Dapper Extension To Insert New Employee Details
                }
            }
            catch (Exception ex)
            {
                return -1;
            }
        }

        public Int32 Update(EmployeeModel Details)
        {
            try
            {
                using (var connection = DBProviderFactory.GetOpenConnection())
                {
                    return Convert.ToInt32(connection.Update(Details)); //Using Dapper Extension to Update Employee Details
                }
            }
            catch (Exception ex)
            {
                return -1;
            }
        }



        public IEnumerable<EmployeeModel> AllEmployees()
        {
            try
            {
                using (var connection = DBProviderFactory.GetOpenConnection())
                {
                    //Using multi mapper in Dapper to Fill All Employee Details such as region,state,country,designation details etc..
                    string query = @"select e.EmpID,e.FirstName,e.MiddleName,e.LastName,e.Address,e.EmailID
                                     ,r.RegionID as RID,r.Region,s.StateID,s.State,c.CountryID,c.Country,d.DesgID as DID,d.Designation
                                       from employee as e inner join region as r on e.RegionID=r.RegionID
                                           inner join state as s on r.StateID=s.StateID inner join country as c on 
                                               s.CountryID=c.CountryID inner join designation as d on e.DesgID=d.DesgID";
                    return connection.Query<EmployeeModel, RegionModel, StateModel, CountryModel,DesignationModel, EmployeeModel>(query,
                        (employee, region, state, country, designation) =>
                        {
                            employee.Region = region;
                            region.State = state;
                            state.Country = country;
                            employee.Designation = designation;
                            return employee;
                        }, splitOn: "RID,StateID,CountryID,DID");
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }

    }

    public class EmployeeModelMapper : ClassMapper<EmployeeModel>
    {
        public EmployeeModelMapper()
        {
            Map(m => m.Region).Ignore();
            Map(m => m.Designation).Ignore();
            Map(m => m.First).Column("FirstName"); //Trying to map table column FirstName to variable First (Fails in the case of Multimapping)
            AutoMap();
        }
    }

在上面的示例中,我尝试将表列 FirstName 映射到类变量 First 但在使用 Dapper connection.Query() 运行查询时失败,请参阅 AllEmployees() 中的 AllEmployees() 方法@类。

我尝试使用 Dapper Mapper 扩展的另一个选项,也可以在上面的代码中找到,参考 EmployeeModelMapper 类。

我的问题:

如何将所有表列映射到对应的类变量,以便在 Dapper 和扩展中通用。

【问题讨论】:

    标签: c# .net sql-server asp.net-mvc-3 dapper


    【解决方案1】:

    Dapper 默认不支持 ColumnKey 等属性属性。

    这里有两个选项,调整您的查询以使用 AS 关键字来更改结果集中的列名称以匹配您的属性名称,这是最简单的选项。

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data.SqlClient;
    using Dapper;
    using Newtonsoft.Json;
    using Repository.DTO;
    
    namespace Repository.Repositories
    {
        public class EmployeeRepo
        {
            public IEnumerable<EmployeeModel> AllEmployees()
            {
                try
                {
                    using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Read"].ConnectionString))
                    {
                        const string query = @"select EmpID, FirstName [First] from employee";
                        return connection.Query<EmployeeModel>(query);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(JsonConvert.SerializeObject(e));
                    throw;
                }
            }
        }
    }
    

    或者,如果这不可能,您可以尝试提供自己的 SqlMapper.ITypeMap 实现。

    一大群人已经以许多不同的方式做到了这一点。我个人是Dapper-FluentMap的粉丝。

    这将是您的 DTO。为了便于配置,我已在 DTO 上嵌入了映射器配置。请注意,您只需列出映射中与返回的列名不同的列。在我们的示例中,只需要 First 属性,因为 EmpId 属性与结果集中的列同名。

    using Dapper.FluentMap.Mapping;
    
    namespace Repository.DTO
    {
        public class EmployeeModel
        {
            public int EmpId { get; set; }
    
            public string First { get; set; }
    
            public class EmployeeModelMap : EntityMap<EmployeeModel>
            {
                public EmployeeModelMap()
                {
                    Map(p => p.First).ToColumn("FirstName");
                }
            }
        }
    }
    

    下一步是初始化您的映射。

    using Dapper.FluentMap;
    using Repository.DTO;
    
    namespace Repository
    {
        public class Bootstrap
        {
            public static void Map()
            {
                FluentMapper.Initialize(config =>
                {
                    config.AddMap(new EmployeeModel.EmployeeModelMap());
                });
            }
        }
    }
    

    那就这样吧。

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data.SqlClient;
    using Dapper;
    using Newtonsoft.Json;
    using Repository.DTO;
    
    namespace Repository.Repositories
    {
        public class EmployeeRepo
        {
            public IEnumerable<EmployeeModel> AllEmployees()
            {
                try
                {
                    using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Read"].ConnectionString))
                    {
                        const string query = @"select EmpID, FirstName from employee";
                        return connection.Query<EmployeeModel>(query);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(JsonConvert.SerializeObject(e));
                    throw;
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      一种简单的方法是将您的 SQL 选择语句更改为使用 AS,它会自动映射。

      所以而不是:

      string query = @"select e.EmpID,e.FirstName, ....
      

      你只需要

      string query = @"select e.EmpID,e.FirstName as First, ....
      

      【讨论】:

      • 我知道。但我想通过映射类属性来克服这个问题。这是我的要求... :( 并感谢您的建议... :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 2019-09-26
      相关资源
      最近更新 更多