存储库级别的最佳方法是为对象的子实体进行水合。例如:我需要系统中所有人的列表。每个人都可以有很多电话号码。我如何在我的存储库中填写所有这些数据?
public class Person
{
public int? Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public List<Phone> PhoneNumbers { get; set; }
}
public IEnumerable<Person> GetPeople()
{
var persons = new List<Person>();
const string sql = "SELECT FirstName, LastName, MiddleName FROM Person.Person";
while (reader.Read())
{
var p = PersonFactory.GetPerson(reader);
p.PhoneNumbers = this.GetPhoneByPersonId(p.Id);
persons.Add(p);
}
return persons;
}
public IEnumerable<Phone> GetPhoneByPersonId(int? id)
{
while (reader.Read())
{
numbers.Add(PersonFactory.GetPhone(reader));
}
}
我对这种方法的问题是我正在执行一堆命中数据库的sql语句。这似乎不是最好的方法。我不能使用任何框架,必须使用DataReader。
我可以采取哪种更好的方法?这也是一个简单的例子。我的Person对象会有更多列表。
答案 0 :(得分:1)
实现GetPeople
方法的一种方法是执行包含多个结果集的单个SQL语句。如果使用启用了MAR S的SQL Server,则它将作为对单个查询的响应来自服务器。否则,您可以执行两个查询,一个用于检索人员,另一个用于检索与这些人员关联的所有电话号码。
您的查询可能类似于:
SELECT FirstName, LastName, MiddleName FROM Person.Person WHERE -- omitted
SELECT PhoneNumber,Name FROM Person.PhoneNumbers WHERE -- restrict to same set as above
同样,如果服务器支持,您可以在单个命令中发送两个查询,也可以发出两个单独的查询。无论哪种方式,这只是两个查询,这没什么大不了的。确保您不会立即返回太多结果。
在内存中有两个结果集后,您可以按人员ID加入它们,并将所有人员实例与相应的电话号码相关联。总的来说,您正在进行一次或两次数据库查询。
IDataReader提供方法NextResult来枚举查询返回的多个结果集。