将数据从2个表映射到单个实体

时间:2015-02-23 03:28:04

标签: c# sql dapper

我有2个表有一对一的关系。表格如下:

CREATE TABLE [dbo].[Provider](
[ProviderId] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[FirstName] [varchar](40) NOT NULL,
[LastName] [varchar](40) NOT NULL,
[SSN] [varchar](15) NOT NULL,
[NPI] [varchar](15) NOT NULL,
[ProviderStatus] [bit] NOT NULL)

CREATE TABLE [dbo].[ProviderDetails](
[ProviderDetailsID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[Certification] [varchar](40) NOT NULL,
[Specialization] [varchar](40) NOT NULL,
[TaxonomyCode] [varchar](40) NOT NULL,
[ContactNumber] [varchar](15) NOT NULL,
[ContactEmail] [varchar](40) NOT NULL,
[ProviderId]  [int] FOREIGN KEY REFERENCES Provider(ProviderId) NOT NULL)

我在C#中创建了2个实体(请注意,我不使用EF)

 public class Provider
{
    public int ProviderID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string SSN { get; set; }
    public string NPI { get; set; }
    public ProviderDetails ProviderDetails { get; set; }
}

public class ProviderDetails
{
    public int ProviderDetailsId { get; set; }
    public string Certification { get; set; }
    public string Specialization { get; set; }
    public string TaxonomyCode { get; set; }
    public string ContactNumber { get; set; }
    public string ContactEmail { get; set; }
    public int ProviderId { get; set; }
}
我早先有一个实体,即提供商。因此,我能够使用以下代码获取要显示的提供程序列表。

    public List<Provider> GetListofProviders()
    {
        List<Provider> Providers = new List<Provider>();
        using (_dbConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["DemoApplicationConnection"].ConnectionString))
        {
            try
            {
                Providers = (List<Provider>)(_dbConnection.Query<Provider>("spGetAllProviders", commandType: CommandType.StoredProcedure));
            }
            catch (Exception)
            {
                throw;
            }
        } 
        return Providers;
    }

要从数据库中获取数据,我使用以下查询:

ALTER PROC [dbo].[spGetAllProviders]
AS
SELECT * FROM Provider 
INNER JOIN ProviderDetails 
ON Provider.ProviderId = ProviderDetails .ProviderId
WHERE Provider.ProviderStatus = 1

由于我已拆分实体,有人可以指导我如何将数据从数据库映射到2个实体吗?

2 个答案:

答案 0 :(得分:0)

有两种方法可以解决这个问题:

编写两个单独的存储过程来从每个表中提取数据,然后将它们加载到各自的对象中:Provider和ProviderDetails。

我能想到的最简单的方法是从存储过程中返回一个DataTable。然后,您可以使用foreach循环访问Datatable中的每个单独节点。您的存储过程调用看起来像这样。

public DataTable GetListofProviders()
{
    DataTable dt = new DataTable();
    SqlCommand cmd = New SqlCommand("spGetAllProviders");
    cmd.CommandType = CommandType.StoredProcedure;
    SqlConnection cn = new SqlConnection(_dbConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["DemoApplicationConnection"].ConnectionString);
    using(cn)
    {
        Try
        {
            SqlDataAdapter da = New SqlDataAdapter(cmd, cn);
            da.Fill(dt);
        }
        Catch (SqlException ex)
        {
            throw ex.Message;
        }
    }

    return dt;
}

这可能不是100%正确,但它很接近。返回数据表后,可以调用函数将每个对象加载到列表中。这看起来有点像这样:

另请注意,这些列表应通过引用传递给加载函数。

public void LoadObjects(ref List<Provider> providers, ref List<ProviderDetail> providerDetail)
{
  DataTable dt = GetListofProviders();
  Provider p = New Provider();
  ProviderDetail pd = new ProviderDetail();
  if(dt.rows.count > 0)
  {
      For Each(DataRow dr in dt)
      {
          p.ProviderID = dr.Item["ProviderId"].ToInt32();
          p.FirstName = dr.Item["FirstName"].ToString();
          .....continue to load object and add it to list
          providers.Add(p);

          pd.ProviderDetailsID = dr.Item["ProviderDetailsID"].ToInt32();
          pd.Certification = dr.Item["Certification"].ToString();
          .....continue to load object and add it to list
          providerDetails.Add(pd);
      }
  }
  else
  {
       ...do something else
  }
}

希望这有帮助!

答案 1 :(得分:0)

现在这不是正确的答案。但我认为这将是可行的方法。虽然它不适合我。所以,如果有人能告诉我我做错了什么,那将非常有帮助。

public List<Provider> GetListofProviders()
{
   List<Provider> Providers = new List<Provider>();
   using (_dbConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["DemoApplicationConnection"].ConnectionString))
   {
       try
       {
          Providers = _dbConnection.Query<Provider,ProviderDetails,Provider>("spGetAllProviders",null,splitOn: "ProviderId", commandType: CommandType.StoredProcedure).ToList();
       }
       catch (Exception)
       {
         throw;
       }
   } 
   return Providers;
}

存储过程也是

ALTER PROC [dbo].[spGetAllProviders]
AS
SELECT Provider.*,
       ProviderDetails.ProviderId,
       ProviderDetails.ProviderDetailsID,
       ProviderDetails.Certification,
       ProviderDetails.Specialization,
       ProviderDetails.TaxonomyCode,
       ProviderDetails.ContactNumber,
       ProviderDetails.ContactEmail 
FROM Provider 
INNER JOIN ProviderDetails 
ON Provider.ProviderId = ProviderDetails .ProviderId
WHERE Provider.ProviderStatus = 1

我收到以下错误。

使用多映射API时,如果您拥有Id以外的密钥,请确保设置splitOn参数