C# 将数据从两个表映射到单个实体

C# 将数据从两个表映射到单个实体,c#,sql,dapper,C#,Sql,Dapper,我有两个表,它们有一对一的关系。这些表如下: 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, [ProviderS

我有两个表,它们有一对一的关系。这些表如下:

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#中创建了两个实体(请注意,我没有使用EF)

一、 早些时候只有一个实体,提供者。因此,我能够使用以下代码获得要显示的提供者列表

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

由于我已拆分了实体,请有人指导我如何将数据库中的数据映射到这两个实体?

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

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

我认为使用的最简单的方法是从存储的proc返回一个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%正确,但很接近。返回datatable后,可以调用函数将每个对象加载到列表中。这看起来有点像这样:

还要注意,这些列表应该通过引用传递到加载函数中

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
  }
}
公共void加载对象(参考列表提供程序、参考列表提供程序详细信息)
{
DataTable dt=GetListofProviders();
Provider p=新的Provider();
ProviderDetail pd=新ProviderDetail();
如果(dt.rows.count>0)
{
对于每个(数据行dr,单位为dt)
{
p、 ProviderID=dr.Item[“ProviderID”].ToInt32();
p、 FirstName=dr.Item[“FirstName”].ToString();
..…继续加载对象并将其添加到列表中
增加(p);
pd.ProviderDetailsID=dr.Item[“ProviderDetailsID”].ToInt32();
pd.Certification=dr.Item[“Certification”].ToString();
..…继续加载对象并将其添加到列表中
供应商详细信息。添加(pd);
}
}
其他的
{
…做点别的
}
}

希望这有帮助

现在这不是正确的答案。但我认为这将是一个可行的方法。虽然这对我不起作用。因此,如果有人能告诉我我做错了什么,那将非常有帮助

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;
}
我得到以下错误

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

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
  }
}
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