[英]C# Populate nested class using foreign key
我需要將來自兩個單獨的數據庫調用的信息拉回到一個對象中。
考慮以下課程
public class Status
{
public int StatusId { get; set; }
public string Name { get; set; }
}
public class Person
{
public int PersonId { get; set; }
public Status PersonStatus { get; set; }
}
這些代表兩個數據庫表Persons和Status,它們與Persons表中的StatusId相關。
CREATE TABLE [dbo].[Status](
[StatusId] [INT] NOT NULL PRIMARY KEY,
[Name] [NVARCHAR](50) NOT NULL )
CREATE TABLE [dbo].[Persons](
[PersonId] [int] NOT NULL PRIMARY KEY,
[StatusId] [int] NOT NULL REFERENCES dbo.Status (StatusId) )
這是獲取人員的過程:
CREATE PROCEDURE dbo.spGetPersons
AS
BEGIN
SELECT PersonId ,
StatusId
FROM dbo.Persons
END
然后,我從SqlDataReader
讀取數據,構造一個Person對象,並返回一個IList<Person>
。 為了填充PersonStatus屬性,當前我將StatusId傳遞到輔助過程中,該過程將再次往返數據庫。
IList<Person> People = new List<Person>();
while (reader.Read())
{
People.Add(new Person()
{
PersonId = (int)reader["PersonId"],
//This causes the extra round trip to the database
StatusId = new StatusDao().GetStatus((int)reader["StatusId"])
});
}
StatusDao().GetStatus()
僅執行以下過程並構造一個Status
對象。
CREATE PROCEDURE dbo.spGetStatus
@StatusId INT = NULL
AS
BEGIN
SELECT StatusId ,
Name
FROM dbo.Status
WHERE @StatusId IS NULL
OR @StatusId = StatusId
END
填充PersonStatus
屬性的正確方法是什么? 顯然,我不應該為每個Person
進行一次額外的數據庫往返之旅。 假設我無法編輯過程,而僅將Name
添加到SQL查詢中。
我沒有看到這個問題,用枚舉建議。 在某些情況下,這是一個不錯的選擇,但是我們假設狀態數據會定期更改。 這使得它不再是一種選擇。
我當前未使用ORM。
我無法添加新的存儲過程,也無法編輯現有的存儲過程。 我也不允許使用內聯SQL。
由於您有一個非常奇怪的要求,即無法添加新的存儲過程或使用內聯SQL; 無論如何,它將需要兩次訪問數據庫(除非再次聲明,狀態是可以在枚舉中捕獲的東西)。
如果您有一個Status
對象和一個Person
對象,並且想要將它們放在一起,則可以使用以下方法:
public static List<Person> GetStatusForPerson(List<Person> people, List<Status> statuses)
{
List<Person> peopleWithStatuses = new List<Person>();
foreach (var p in people)
{
Person person = new Person();
person.PersonId = p.PersonId;
person.Status = statuses.Where(s => s.StatusId == person.StatusId).FirstOrDefault());
peopleWithStatuses.Add(person);
}
return peopleWithStatuses;
}
要在一次數據庫往返中獲取此信息(對於那些沒有奇怪要求的人):
var persons = new List<Person>();
using (SqlConnection connection = new SqlConnection(connectionString)) {
string sqlText = "Select p.PersonId, ps.Name, ps.StatusId FROM Person p INNER JOIN PersonStatus ps on p.StatusID = ps.StatusId WHERE p.PersonId = @personId";
SqlCommand command = new SqlCommand();
command.Parameters.Add("@personId", SqlDbType.Int);
command.Parameters["@personId"].Value = personId;
connection.Open();
using (SqlDataReader reader = command.ExecuteReader()) {
while (reader.Read())
{
var person = new Person();
var status = new PersonStatus();
person.PersonID = reader["PersonId"];
status.StatusId = reader["StatusId"];
status.Name = reader["Name"];
person.Status = status;
persons.Add(person);
}
}
}
return persons;
如果Status
是一系列整數常量(很像enum
),那么您可以簡單地使用enum
並存儲可能的狀態。
如果Status
動態地添加或刪除值,那么在不使用ORM時,您必須求助於恢復數據的常規方法: A DataReader
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.