我有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个实体吗?
答案 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参数