【发布时间】:2014-02-28 16:48:07
【问题描述】:
将服务层的 TransactionScope 中的所有 3 个 dataprovider.GetXXX 方法捆绑为 UnitOfWork 的方法是否正确?
你会做一些不同的事情吗?
TransactionScpets 从哪里知道具体的 ConnectionString?
我应该从我的连接中获取 Transaction 对象并将这个 Transaction 对象传递给 TransactionScope 的构造函数吗?
像 AdministrationService.cs 这样的服务层
private List<Schoolclass> GetAdministrationData()
{
List<Schoolclass> schoolclasses = null
using (TransactionScope ts = new TransactionScope())
{
schoolclasses = _adminDataProvider.GetSchoolclasses();
foreach (var s in schoolclasses)
{
List<Pupil> pupils = _adminDataProvider.GetPupils(s.Id);
s.Pupils = pupils;
foreach (var p in pupils)
{
List<Document> documents = _documentDataProvider.GetDocuments(p.Id);
p.Documents = documents;
}
}
ts.Complete();
}
return schoolclasses;
}
举例说明 DataProvider 中这 3 种方法的外观:
public List<Schoolclass> GetSchoolclassList()
{
// used that formerly without TransactionSCOPE => using (var trans = DataAccess.ConnectionManager.BeginTransaction())
using (var com = new SQLiteCommand(DataAccess.ConnectionManager))
{
com.CommandText = "SELECT * FROM SCHOOLCLASS";
var schoolclasses = new List<Schoolclass>();
using (var reader = com.ExecuteReader())
{
Schoolclass schoolclass = null;
while (reader.Read())
{
schoolclass = new Schoolclass();
schoolclass.SchoolclassId = Convert.ToInt32(reader["schoolclassId"]);
schoolclass.SchoolclassCode = reader["schoolclasscode"].ToString();
schoolclasses.Add(schoolclass);
}
}
// Used that formerly without TransactionSCOPE => trans.Commit();
return schoolclasses;
}
}
【问题讨论】:
-
TransactionScope 通常应该在进行数据修改或其他应该是“全有或全无”操作的操作(非数据库相关)时使用。从数据库中选择数据实际上不是一个事务。此外,如果您需要所有这些结果,您应该在一次对数据库的查询中获得多个结果集。在您的情况下,由于您没有使用存储过程,因此您应该在一个查询(CommandText)中有多个选择语句。然后,DataReader 将具有多个结果集,您可以使用 DbDataReader 的 NextResult() 方法对其进行迭代。
-
TransactionScope 使底层 ADO.NET 提供程序知道(反之亦然),因此您在 TransactionScope 的范围/生命周期内执行的任何操作都会自动参与事务。因此,它比经典的“connection.BeginTransaction()”api 更容易使用。
-
@Shiv 好的,我的样本在选择时有点愚蠢...用于更新、插入、删除其有效。是的,我知道数据读取器的 .NextResult() 方法,但有一件事我不能使用它。假设我在第一个 select 语句中获得了所有 Schoolclasses。您如何将结果集的 EACH schoolclassId 传递给第二个 select 语句,为 EACH SchoolclassId 获取学生?我不使用存储过程。我使用了一个简单的 Comment.Text = "Select .... fields from table"
-
示例:com.CommandText = "从学校班级中选择 *;从学生中选择 *;从文档中选择 *";这是一个非常简单的示例,实际上我有一个从学生到文档的 N:M 关系...@Shiv 假设我在阅读器中有这 3 个结果集并做了 2 次 reader.NextResult() 我是对的,我仍然有比较 schoolclassId 和 student.schoolclassId 以了解哪个学生属于哪个 schoolclass.Pupils 集合?
-
@Shiv 结果集的坏处是我必须获取所有文档,因为在我使用 3 个 Select 语句构建查询的那一刻,我不知道与 PUPIL_DOCUMENT 相关的每个学生 ID再次引用 DOCUMENT 表的表。到目前为止,我可以看到没有适合我的 ResultSet。
标签: c# transactions transactionscope