所以我已经阅读了很多链接/ SO问题,但我仍然无法得到明确的答案。
在ASP.NET应用程序中使用Dapper执行SQL查询时,打开/关闭连接的最佳做法是什么?
这是我目前关注的模式:
using (var db = new SqlConnection(_connectionString))
{
return db.Query("dbo.SomeQuery");
}
基本上,每次根据需要打开/关闭SQL连接。
根据我的理解,上面的代码应该自动打开/关闭SQL连接(例如,我不需要明确做db.Open
或db.Close
)。
我看到的问题是,过了一段时间,我得到了一堆这些错误:
InvalidOperationExceptionTimeout已过期。超时时间已过 在从池中获取连接之前。这可能已经发生过 因为所有池化连接都在使用中,并且最大池大小为 达到。
在此期间我有一个SQL探查器跟踪,并且我没有看到任何会阻止任何内容的长查询,因此看起来好像我的ASP.NET Web应用程序连接不足(而不是花太长时间来执行查询)。
有人可以告诉我我做错了吗?
旁注:我的应用程序是作为Azure Web App运行的,所以很遗憾,我无法实际看到Web应用程序正在打开多少个连接。 :(
答案 0 :(得分:1)
这里是内部使用Dapper的数据库上下文的一个示例,我认为这是好的最佳实践。我将其整合到一个项目中,它具有不断发展的变化,来自不同地方的最佳创意以及我自己的一些经验/投入。此上下文还示例了不同类型的数据库操作:
此外,ASP.NET Core Options模式用于注入设置/连接字符串信息,与Dapper无关,但我仍然很容易看到,因为Dapper在.NET应用程序中大量使用。
我介绍了一种代码风格的概念,即将与原始数据混合在一起的类称为“实体”,并将为调用者清除的转换后的数据称为“模型”。 “ ViewModel”专用于我的堆栈中的前端。有时,上下文会向调用者返回模型,有时会返回原始实体,因为调用者需要原始实体进行深度转换,而不是上下文应负责。这个概念可能不是完美的,我在某些方面自行弥补,因为我发现“模型”一词在不同的堆栈,团队和公司中具有多种含义。我们为世界建模,数据库可以被称为模型,实体可以被视为模型...无论如何,我所说的是一门艺术和一门科学,只是试图在下面的代码中更好地解释返回类型。 :)
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using Dapper;
using Microsoft.Extensions.Options;
using Tsl.CustomPrice.Interfaces;
using Tsl.CustomPrice.Model;
using Tsl.CustomPrice.Model.Configuration;
using Tsl.CustomPrice.Model.Tso;
using Tsl.Shared.Enumeration;
namespace Tsl.CustomPrice.Data
{
public class TsoContext : ITsoContext
{
private readonly string _connectionString;
private IDbConnection Connection => new SqlConnection(_connectionString);
public TsoContext(IOptions<DbSettings> settings)
{
_connectionString = settings.Value.ConnectionStrings.TsoConnection;
}
#region Custom Price Column
public int GetCustomPriceColumnCountForUser(int userId)
{
using (IDbConnection conn = Connection)
{
var query = @"SELECT count(*)
FROM [TSO].[dbo].[CustomPriceColumn] (NOLOCK)
WHERE [EntityID] = @userId and [EntityTypeID] = 1 --User";
return conn.ExecuteScalar<int>(query, new { userId });
}
}
public CustomPriceColumnModel GetLastUpdatedCustomPriceColumn(int userId)
{
using (IDbConnection conn = Connection)
{
var query = @"SELECT [CustomPriceColumnID]
,[EntityID]
FROM [TSO].[dbo].[CustomPriceColumn] (NOLOCK)
WHERE [EntityID] = @userId and [EntityTypeID] = 1 --User
ORDER BY [LastUpdatedDateTime] desc";
return conn.Query<CustomPriceColumnModel>(query, new { userId }).FirstOrDefault();
}
}
public CustomPriceColumnModel GetCustomPriceColumn(int customPriceColumnId, int userId)
{
using (IDbConnection conn = Connection)
{
const string query = @"SELECT [CustomPriceColumnID]
,[EntityID]
,[EntityTypeID]
,[CustomPriceColumnTypeID]
,a.[CreatedDateTime]
,case when (CreatedByUserID = @userId or CustomPriceColumnTypeID = 2) then 1 else 0 end as IsEditable
,b.FirstName as CreatedByFirstName
,b.LastName as CreatedByLastName
FROM [dbo].[CustomPriceColumn] a (nolock)
left join [User] b on b.UserID = a.CreatedByUserID
WHERE [CustomPriceColumnID] = @customPriceColumnId";
return conn.QueryFirstOrDefault<CustomPriceColumnModel>(query, new { @customPriceColumnId=customPriceColumnId, @userId=userId });
}
}
public IEnumerable<CustomPriceColumnModel> GetCustomPriceColumns(int userId)
{
using (IDbConnection conn = Connection)
{
const string query = @"SELECT
[CustomPriceColumnID]
,[EntityID]
,[EntityTypeID]
,case when (CreatedByUserID = @userId or CustomPriceColumnTypeID = 2) then 1 else 0 end as IsEditable
,b.FirstName as CreatedByFirstName
,b.LastName as CreatedByLastName
FROM CustomPriceColumn cpc (nolock)
inner join [User] u (nolock)
on u.UserID = @userId
left join [User] b on b.UserID = CreatedByUserID
WHERE (EntityID = @userId and EntityTypeID = 1)
or (CreatedByUserID = @userId)
or (EntityID = u.CompanyID and EntityTypeID = 0)";
return conn.Query<CustomPriceColumnModel>(query, new { userId });
}
}
public int CreateCustomPriceColumn(string customPriceColumnName, string customPriceColumnDescription, int entityId, int createdByUserId, string countryCode, IndustryTypes industryTypeId, EntityTypes entityTypeId, CustomPriceColumnTypes customPriceColumnTypeId, string systemUserName, string actorName)
{
using (IDbConnection conn = Connection)
{
var query = @"INSERT INTO [TSO].[dbo].[CustomPriceColumn]
([EntityID]
,[EntityTypeID]
,[CustomPriceColumnTypeID]
,[CreatedByUserID]
,[IndustryTypeID]
,[CountryCode]
,[CustomPriceColumnName]
,[CustomPriceColumnDescription]
,[CreatedDateTime]
,[LastUpdatedDateTime]
,[ActorName]
,[SystemUserName])
VALUES
(@entityId
,@entityTypeId
,@customPriceColumnTypeId
,@createdByUserId
,@industryTypeId
,@countryCode
,@customPriceColumnName
,@customPriceColumnDescription
,getdate()
,getdate()
,@actorName
,@systemUserName);
SELECT CAST(SCOPE_IDENTITY() as int)";
return conn.ExecuteScalar<int>(query,
new
{
entityId,
entityTypeId,
customPriceColumnTypeId,
createdByUserId,
industryTypeId,
countryCode,
customPriceColumnName,
customPriceColumnDescription,
actorName,
systemUserName
});
}
}
public void UpdateCustomPriceColumn(int customPriceColumnId, string customPriceColumnName, string customPriceColumnDescription, int entityId, IndustryTypes industryTypeId, EntityTypes entityTypeId, CustomPriceColumnTypes customPriceColumnTypeId, string systemUserName, string actorName)
{
using (IDbConnection conn = Connection)
{
var query = @"UPDATE [TSO].[dbo].[CustomPriceColumn]
SET [EntityID] = @entityId
,[EntityTypeID] = @entityTypeId
,[CustomPriceColumnTypeID] = @customPriceColumnTypeId
,[IndustryTypeID] = @industryTypeId
,[CustomPriceColumnName] = @customPriceColumnName
,[CustomPriceColumnDescription] = @customPriceColumnDescription
,[LastUpdatedDateTime] = getdate()
WHERE [CustomPriceColumnID] = @customPriceColumnId";
conn.Execute(query,
new
{
customPriceColumnId,
entityId,
entityTypeId,
customPriceColumnTypeId,
industryTypeId,
customPriceColumnName,
customPriceColumnDescription,
actorName,
systemUserName
});
}
}
public void DeleteCustomPriceColumn(int customPriceColumnId)
{
using (IDbConnection conn = Connection)
{
var query = @"DELETE FROM [TSO].[dbo].[CustomPriceColumn]
WHERE [CustomPriceColumnID] = @customPriceColumnId";
conn.Execute(query,
new
{
customPriceColumnId
});
}
}
public CustomPriceColumnMetaDataForCpfExportEntity GetCustomPriceColumnMetaDataForCpfExport(int customPriceColumnId)
{
var ret = new CustomPriceColumnMetaDataForCpfExportEntity();
using (IDbConnection conn = Connection)
{
const string query = @"
-- TOTAL RULES VS. TOTAL PERCENT RULES
SELECT tr.TotalRules, trp.TotalPercentRules FROM
(SELECT CustomPriceColumnId, COUNT(*) AS TotalRules FROM tso.dbo.CustomPriceRule WHERE CustomPriceColumnID = @CustomPriceColumnId GROUP BY CustomPriceColumnID) as tr
JOIN
(SELECT CustomPriceColumnId, COUNT(*) AS TotalPercentRules FROM tso.dbo.CustomPriceRule WHERE CustomPriceColumnID = @CustomPriceColumnId AND IsPercent = 1 GROUP BY CustomPriceColumnID) AS trp
ON tr.CustomPriceColumnID = trp.CustomPriceColumnID;
-- TOTAL RULES BY BASE COLUMN
SELECT BaseColumnPriceTypeID, OperationTypeId, COUNT(*) AS TotalRules FROM tso.dbo.CustomPriceRule WHERE CustomPriceColumnID = @CustomPriceColumnId
GROUP BY BaseColumnPriceTypeID, OperationTypeId";
using (SqlMapper.GridReader multi = conn.QueryMultiple(query, new { @customPriceColumnId = customPriceColumnId }))
{
ret.MetaData = multi.Read<CustomPriceColumnMetaDataEntity>().SingleOrDefault();
ret.BasePriceColumnRuleCounts = multi.Read<BasePriceColumnRuleCountEntity>().ToList();
}
return ret;
}
}
#endregion
#region Custom Price Rule
public IEnumerable<int> GetCustomPriceRulesIds(int customPriceColumnId)
{
using (IDbConnection conn = Connection)
{
var query =
@"SELECT [CustomPriceRuleId] FROM [dbo].[CustomPriceRule] (nolock) WHERE [CustomPriceColumnId] = @customPriceColumnId";
return conn.Query<int>(query, new {customPriceColumnId});
}
}
public IEnumerable<CustomPriceRuleModel> GetCustomPriceRules(int customPriceColumnId, int index, int pageSize)
{
//implementation can be extended to allow sorting by other
var sortBy = "a.CreatedDateTime desc";
using (IDbConnection conn = Connection)
{
var query = @"SELECT *
FROM
(SELECT ROW_NUMBER() OVER ( ORDER BY {0}) AS RowNum,
COUNT(*) OVER () AS TotalRows,
[CustomPriceRuleId]
FROM [dbo].[CustomPriceRule] a (nolock)
left outer join [dbo].[Commodity] b (nolock) on a.CommodityId = b.CommodityID
left outer join [dbo].[Company] c (nolock) on a.ManufacturerCompanyId = c.CompanyId
left outer join [dbo].[Item] d (nolock) on a.ItemId = d.ItemID
WHERE [CustomPriceColumnId] = @customPriceColumnId
) AS result
WHERE RowNum BETWEEN ( ((@index - 1) * @pageSize )+ 1) AND @index*@pageSize
ORDER BY RowNum";
query = string.Format(query, sortBy);
return conn.Query<CustomPriceRuleModel>(query, new { customPriceColumnId, index, pageSize });
}
}
public CustomPriceRuleModel GetCustomPriceRule(int customPriceRuleId)
{
using (IDbConnection conn = Connection)
{
const string query = @"SELECT [CustomPriceRuleId]
,[CustomPriceColumnId]
FROM [TSO].[dbo].[CustomPriceRule]
WHERE [CustomPriceRuleId] = @customPriceRuleId";
return conn.QueryFirstOrDefault<CustomPriceRuleModel>(query, new { customPriceRuleId });
}
}
public CustomPriceRuleModel GetCustomPriceRuleByItemId(int customPriceColumnId, int itemId)
{
using (IDbConnection conn = Connection)
{
const string query = @"SELECT [CustomPriceRuleId]
,[CustomPriceColumnId]
,[CustomPriceRuleLevelId]
FROM [TSO].[dbo].[CustomPriceRule]
WHERE [CustomPriceColumnId] = @customPriceColumnId and [ItemId] = @itemId";
return conn.QueryFirstOrDefault<CustomPriceRuleModel>(query, new { customPriceColumnId, itemId });
}
}
public CustomPriceRuleModel FindCustomPriceRule(int customPriceColumnId, CustomPriceRuleLevels customPriceRuleLevel,
int? itemId, int? manufacturerCompanyId, int? commodityId, string ucc)
{
using (IDbConnection conn = Connection)
{
string query = @"SELECT [CustomPriceRuleId]
,[CustomPriceColumnId]
,[UCC]
FROM [TSO].[dbo].[CustomPriceRule]
WHERE [CustomPriceColumnId] = @customPriceColumnId
AND [CustomPriceRuleLevelId] = @customPriceRuleLevel";
var parameters = new DynamicParameters();
parameters.Add("@customPriceColumnId", customPriceColumnId);
parameters.Add("@customPriceRuleLevel", (int)customPriceRuleLevel);
switch (customPriceRuleLevel)
{
case (CustomPriceRuleLevels.Item):
query += @" AND ItemId = @itemId";
parameters.Add("@itemId", itemId);
break;
case (CustomPriceRuleLevels.ManufacturerAndCommodity):
query += @" AND ManufacturerCompanyID = @manufacturerCompanyId
AND CommodityId = @commodityId";
parameters.Add("@manufacturerCompanyId", manufacturerCompanyId);
parameters.Add("@commodityId", commodityId);
break;
case (CustomPriceRuleLevels.Manufacturer):
query += @" AND ManufacturerCompanyID = @manufacturerCompanyId";
parameters.Add("@manufacturerCompanyId", manufacturerCompanyId);
break;
case (CustomPriceRuleLevels.Commodity):
query += @" AND CommodityId = @commodityId";
parameters.Add("@commodityId", commodityId);
break;
case (CustomPriceRuleLevels.Ucc):
query += @" AND ManufacturerCompanyID = @manufacturerCompanyId
AND Ucc = @ucc";
parameters.Add("@manufacturerCompanyId", manufacturerCompanyId);
parameters.Add("@ucc", ucc);
break;
}
return conn.QueryFirstOrDefault<CustomPriceRuleModel>(query, parameters);
}
}
public void UpdateCustomPriceRule(int customPriceRuleId, CustomPriceRuleLevels customPriceRuleLevel, int? itemId, int? manufactuerCompanyId,
int? commodityId, PriceTypes? baseColumnPriceTypeId, CustomPriceOperations? operationTypeId, decimal customPriceRuleValue, bool isPercent, string customPriceRuleDescription,
Uom? fixedPriceUnitIfMeasureTypeCode, string ucc, string actorName, string systemUsername)
{
using (IDbConnection conn = Connection)
{
var query = @"UPDATE [TSO].[dbo].[CustomPriceRule]
SET [CustomPriceRuleLevelId] = @customPriceRuleLevel
,[ItemId] = @itemId
,[ManufacturerCompanyId] = @manufactuerCompanyId
,[CommodityId] = @commodityId
,[BaseColumnPriceTypeId] = @baseColumnPriceTypeId
,[OperationTypeId] = @operationTypeId
,[CustomPriceRuleValue] = @customPriceRuleValue
,[IsPercent] = @isPercent
,[CustomPriceRuleDescription] = @customPriceRuleDescription
,[FixedPriceUnitOfMeasureTypeCode] = @strUom
,[LastUpdatedDateTime] = getdate()
,[ActorName] = @actorName
,[SystemUsername] = @systemUsername
,[UCC] = @ucc
WHERE [CustomPriceRuleId] = @customPriceRuleId";
var strUom = fixedPriceUnitIfMeasureTypeCode != null ? fixedPriceUnitIfMeasureTypeCode.ToString() : null;
// HACK: See TSL-1235 : CustomPriceOperations.FixedPrice must translate to a null in the CustomPriceRule row.
CustomPriceOperations? opTypeId = operationTypeId == CustomPriceOperations.FixedPrice ? null : operationTypeId;
conn.Execute(query,
new
{
customPriceRuleId,
customPriceRuleLevel,
itemId,
manufactuerCompanyId,
commodityId,
baseColumnPriceTypeId,
operationTypeId = opTypeId,
customPriceRuleValue,
isPercent,
customPriceRuleDescription,
strUom,
ucc,
actorName,
systemUsername
});
}
}
public int CreateCustomPriceRule(int customPriceColumnId, CustomPriceRuleLevels customPriceRuleLevel, int? itemId,
int? manufactuerCompanyId, int? commodityId, PriceTypes? baseColumnPriceTypeId, CustomPriceOperations? operationTypeId,
decimal customPriceRuleValue, bool isPercent, string customPriceRuleDescription, Uom? fixedPriceUnitIfMeasureTypeCode,
string ucc, string actorName, string systemUsername)
{
using (IDbConnection conn = Connection)
{
var query = @"INSERT INTO [TSO].[dbo].[CustomPriceRule]
([CustomPriceColumnId]
,[CustomPriceRuleLevelId]
,[ItemId]
,[ManufacturerCompanyId]
,[CommodityId]
,[BaseColumnPriceTypeId]
,[OperationTypeId]
,[CustomPriceRuleValue]
,[IsPercent]
,[CustomPriceRuleDescription]
,[FixedPriceUnitOfMeasureTypeCode]
,[CreatedDateTime]
,[LastUpdatedDateTime]
,[ActorName]
,[SystemUsername]
,[UCC])
VALUES
(@customPriceColumnId
,@customPriceRuleLevel
,@itemId
,@manufactuerCompanyId
,@commodityId
,@baseColumnPriceTypeId
,@operationTypeId
,@customPriceRuleValue
,@isPercent
,@customPriceRuleDescription
,@strUom
,getdate()
,getdate()
,@actorName
,@systemUsername
,@ucc);
SELECT CAST(SCOPE_IDENTITY() as int)";
var strUom = fixedPriceUnitIfMeasureTypeCode != null ? fixedPriceUnitIfMeasureTypeCode.ToString() : null;
return conn.ExecuteScalar<int>(query,
new
{
customPriceColumnId,
customPriceRuleLevel,
itemId,
manufactuerCompanyId,
commodityId,
baseColumnPriceTypeId,
operationTypeId,
customPriceRuleValue,
isPercent,
customPriceRuleDescription,
strUom,
ucc,
actorName,
systemUsername
});
}
}
public void DeleteCustomPriceRule(int customPriceRuleId)
{
using (IDbConnection conn = Connection)
{
var query = @"DELETE FROM [TSO].[dbo].[CustomPriceRule]
WHERE [CustomPriceRuleId] = @customPriceRuleId";
conn.Execute(query,
new
{
customPriceRuleId
});
}
}
public void DeleteCustomPriceRules(IEnumerable<int> customPriceRuleIds)
{
var cprIdsList = customPriceRuleIds.ToList();
if (!cprIdsList.Any()) return;
using (IDbConnection conn = Connection)
{
var query = @"DELETE FROM [TSO].[dbo].[CustomPriceRule]
WHERE [CustomPriceRuleId] in ("
+ string.Join(",", cprIdsList)
+ ")";
conn.Execute(query);
}
}
public List<CustomPriceRuleForExportEntity> GetCustomPriceRulesForExport(int customPriceColumnId)
{
using (IDbConnection conn = Connection)
{
const string query = @"SELECT
cpr.CustomPriceRuleLevelID
,cpr.Ucc
,i.Upc
,c.CommodityCode
,mu.ShortName as ManufacturerShortName
,i.ManufacturerCatalogCode
,cpr.CustomPriceRuleDescription
,cpr.BaseColumnPriceTypeId
,cpr.OperationTypeId
,cpr.CustomPriceRuleValue
,cpr.IsPercent
,cpr.ItemId
,cpr.ManufacturerCompanyId
,cpr.CommodityId
FROM TSO.dbo.CustomPriceRule cpr
LEFT OUTER JOIN TSO.dbo.Item i ON cpr.ItemId = i.ItemId
LEFT OUTER JOIN TSO.dbo.ManufacturerUcc mu
ON ((cpr.CustomPriceRuleLevelId <> 1 AND cpr.ManufacturerCompanyId = mu.CompanyID AND cpr.UCC = mu.UCC)
OR (cpr.CustomPriceRuleLevelId = 1 AND LEFT(i.UPC, 6) = mu.UCC) and i.ManufacturerCompanyID = mu.CompanyID)
LEFT OUTER JOIN TSO.dbo.Commodity c ON cpr.CommodityId = c.CommodityId
WHERE cpr.CustomPriceColumnId = @customPriceColumnId";
return conn.Query<CustomPriceRuleForExportEntity>(query, new { @customPriceColumnId = customPriceColumnId }).ToList();
}
}
#endregion
public bool IsAllowedToModifyCustomPriceColumn(int userId, int customPriceColumnId)
{
using (IDbConnection conn = Connection)
{
// Check access to CP colummn.
var getCpQuery = @"SELECT [CustomPriceColumnID]
FROM [CustomPriceColumn] cpc
JOIN [User] u ON u.UserId = @userId
WHERE cpc.[CustomPriceColumnId] = @customPriceColumnId
AND ((cpc.[CreatedByUserID] = @userId) /* Created by the User */
OR (cpc.EntityID = u.CompanyId and cpc.EntityTypeID = 0 AND CustomPriceColumnTypeID = 2)) /* OR CREATED BY SOMEONE IN THE COMPANY AND MARKED PUBLIC-EDITABLE */";
return conn.Query<CustomPriceColumnModel>(getCpQuery, new { @customPriceColumnId = customPriceColumnId, @userId = userId }).SingleOrDefault() != null;
}
}
}
}
答案 1 :(得分:0)
从我的观点来看,使用语句关闭你的连接,但你告诉明确打开这样的连接:
using (var db = new SqlConnection(_connectionString))
{
db.open();
return db.Query("dbo.SomeQuery");
}
答案 2 :(得分:0)
using块将处理资源管理,因此您不需要手动关闭连接,此外,手动关闭连接还会阻止连接池并降低性能。
答案 3 :(得分:0)
根据我对这种非常相似的体验的经验,超时可能是由于SQL连接超时引起的。这可能是因为,假设您的SQL Server在X核心服务器上运行,并且所有可能的最大连接数被并发调用使用,随后的调用进入等待模式。如果未指定,它将采用默认的连接超时。
您可能想在连接字符串或数据存储层中覆盖它。检查ConnectionTimeout属性。
答案 4 :(得分:0)
在我看来,您的代码很好,Dapper会打开和关闭集合本身,但是您得到的例外是因为连接池没有空闲连接可在超时时间返回。其原因可能是:
- 您的查询是长期运行的
- 对于您所承载的用户,您的连接池大小较小 有(默认为100)
- 1和2的组合
因此,根据您的需要调整连接池大小,并调整查询和数据库本身。或使用更大的连接超时。
PS::当您手动关闭连接时,Connection Pool实际上不会关闭它,因为打开和关闭与数据库的连接的成本很高,因此打开Dapper并没有问题。并关闭连接本身。
答案 5 :(得分:0)
我遇到了您的问题。我用dapper做我的工作项目。我也遇到过同样的问题。
首先,您应该对SQL Server执行“ sp_who2”以打开sql连接
此代码返回:总连接大小,数据库名称,被阻止的人和状态
例如:
此图像是在Azure Sql数据库中拍摄的
"diff": [
"1" : "2 days ago",
输入会话ID以查找查询
SELECT s.session_id,
r.status,
r.blocking_session_id 'Blk by',
r.wait_type,
wait_resource,
r.wait_time / (1000.0) 'Wait Sec',
r.cpu_time,
r.logical_reads,
r.reads,
r.writes,
r.total_elapsed_time / (1000.0) 'Elaps Sec',
Substring(st.TEXT,(r.statement_start_offset / 2) + 1,
((CASE r.statement_end_offset
WHEN -1
THEN Datalength(st.TEXT)
ELSE r.statement_end_offset
END - r.statement_start_offset) / 2) + 1) AS statement_text,
Coalesce(Quotename(Db_name(st.dbid)) + N'.' + Quotename(Object_schema_name(st.objectid,st.dbid)) + N'.' + Quotename(Object_name(st.objectid,st.dbid)),
'') AS command_text,
r.command,
s.login_name,
s.host_name,
s.program_name,
s.last_request_end_time,
s.login_time,
r.open_transaction_count
FROM sys.dm_exec_sessions AS s
JOIN sys.dm_exec_requests AS r
ON r.session_id = s.session_id
CROSS APPLY sys.Dm_exec_sql_text(r.sql_handle) AS st
WHERE r.session_id = 122
ORDER BY r.cpu_time desc, r.status,
r.blocking_session_id,
s.session_id
public T WithConnection<T>(Func<IDbConnection, T> dbOperation)
{
try
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DatabaseName"].ConnectionString))
{
var result = dbOperation(connection);
connection.Close();
return result;
}
}
catch (TimeoutException ex)
{
throw new Exception(String.Format("{0}.WithConnection() experienced a SQL timeout", GetType().FullName), ex);
}
catch (SqlException ex)
{
throw new Exception(String.Format("{0}.WithConnection() experienced a SQL exception (not a timeout)", GetType().FullName), ex);
}
catch (InvalidOperationException ex)
{
throw new Exception(String.Format("{0}.WithConnection() experienced a InvalidOperationException", GetType().FullName), ex);
}
}
这解决了我的问题
答案 6 :(得分:0)
我为dapper定义了通用包装器:)
class DapperWrapper<T>
{
private static string connectionString = "your connection string";
public static List<T> Get_List(string query, DynamicParameters args = null)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
List<T> result = new List<T>();
try
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
result = connection.Query<T>(query, args).ToList();
connection.Close();
}
return result;
}
catch (Exception ex)
{
SqlException(query, ex.Message, watch.ElapsedMilliseconds);
}
finally
{
watch.Stop();
}
return null;
}
public static T Get_Single(string query, DynamicParameters args = null)
{
T result;
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
result = connection.Query<T>(query, args).FirstOrDefault();
connection.Close();
}
return result;
}
catch (Exception ex)
{
SqlException(query, ex.Message, watch.ElapsedMilliseconds);
}
finally
{
watch.Stop();
}
return default(T);
}
public static bool Execute(string query, DynamicParameters args = null, Log logSuccess = null)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
var isSuccess = connection.Execute(query, args)> 0;
if (isSuccess && logSuccess != null)
Logs.Add(logSuccess);
connection.Close();
return isSuccess;
}
}
catch (Exception ex)
{
SqlException(query, ex.Message, watch.ElapsedMilliseconds);
}
finally
{
watch.Stop();
}
return false;
}
private static void SqlException(string query, string exception, long elapsedMilliseconds)
{
var error = $"query : {query} → exception : {exception} → time : {elapsedMilliseconds}";
Logs.Add(
new Log()
{
Title = "Error in dapper",
Description = error
}
);
}
}
您可以使用以下示例
#------------Get list
IList<Post> posts = DapperWrapper<Post>.Get_List("SELECT * FROM posts");
#------------Get single
Post post = DapperWrapper<Post>.Get_Single("SELECT * FROM posts where id=1");
#------------Excute
bool isSuccess = DapperWrapper<Post>.Execute("DELETE posts where id=1");
#------------Excute with parameter
SqlParameter[] parameters = {
new SqlParameter("@Id",1)
};
var args = new DynamicParameters(new { });
parameters.ToList().ForEach(p => args.Add(p.ParameterName, p.Value));
bool isSuccess = DapperWrapper<Post>.Execute("DELETE posts where id=@Id", args);