小编Dan*_*ann的帖子

在sql_variant列的表值参数中传递'object'类型的参数

我在SQL Server 2012中有一个表值参数定义为:

CREATE TYPE [dbo].[TVP] AS TABLE (
    [Id] [int] NOT NULL,
    [FieldName] [nvarchar](100) NOT NULL,
    [Value] [sql_variant] NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

我在C#中使用代码看起来大致如下所示:

var mdItems = new DataTable();
mdItems.Columns.Add("Id", typeof(int));
mdItems.Columns.Add("FieldName", typeof(string));
mdItems.Columns.Add("Value", typeof(object));
mdItems.Rows.Add(new object[] {2, "blah", "value"}); //'value' is usually a string
SqlCommand sqlCommand = conn.CreateCommand();
sqlCommand.CommandText = "[WriteFieldValues]";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("@FieldValues", mdItems);
sqlCommand.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)

然后,我在ExecuteNonQuery调用SQL Server时收到以下错误:

不支持"值"列的类型.类型是'对象'

我发现有人在3年前遇到了同样的问题,当时它被认定为已知的Microsoft bug.但是,该错误的链接已被破坏.有谁知道是否有关于错误状态或潜在解决方法的最新信息?就目前而言,这个错误确实会破坏sql_variant字段的价值.

c# sql-server sql-variant table-valued-parameters sql-server-2012

15
推荐指数
2
解决办法
3519
查看次数

使用CancellationToken取消SQL Server查询

我在SQL Server中有一个长期运行的存储过程,我的用户需要能够取消它.我写了一个小测试应用程序,如下所示,该SqlCommand.Cancel()方法可以很好地运行:

    private SqlCommand cmd;
    private void TestSqlServerCancelSprocExecution()
    {
        TaskFactory f = new TaskFactory();
        f.StartNew(() =>
            {
              using (SqlConnection conn = new SqlConnection("connStr"))
              {
                conn.InfoMessage += conn_InfoMessage;
                conn.FireInfoMessageEventOnUserErrors = true;
                conn.Open();

                cmd = conn.CreateCommand();
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "dbo.[CancelSprocTest]";
                cmd.ExecuteNonQuery();
              }
           });
    }

    private void cancelButton_Click(object sender, EventArgs e)
    {
        if (cmd != null)
        {
            cmd.Cancel();
        }
    }
Run Code Online (Sandbox Code Playgroud)

在调用时cmd.Cancel(),我可以验证基础存储过程基本上立即停止执行.鉴于我在我的应用程序中使用了异步/等待模式,我希望SqlCommand采用CancellationToken参数的异步方法同样可以正常工作.不幸的是,我发现,呼吁Cancel()CancellationToken造成InfoMessage事件处理程序不再被调用,但底层的存储过程继续执行.我的异步版本的测试代码如下:

    private SqlCommand cmd;
    private CancellationTokenSource cts; …
Run Code Online (Sandbox Code Playgroud)

c# sql-server async-await cancellationtokensource

14
推荐指数
1
解决办法
8375
查看次数

在哪里可以找到有关在.NET中处理COM资源的更多详细信息?

我的问题的背景是:我正在转换一个消息处理应用程序,它使用从VB6到C#的许多COM组件.应用程序中的许多COM组件都是细粒度组件,在消息处理循环中使用的数量和频率都很高.与VB6应用程序相比,在C#应用程序中处理一组测试消息时,我看到内存使用量大幅增加(且逐渐增长).我在应用程序上使用了一个内存分析器,它确认了高内存使用量是由应用程序的非托管堆上的COM对象的实时实例引起的.我知道这些组件由于实时引用而没有被"泄露",因为如果我将GC.Collect()放在消息处理循环的核心,那么内存使用率是平坦的,几乎与VB6应用程序相同(尽管性能像人们期望的那样可怕地降级.

我已经阅读了我在C#中的多代垃圾收集器,运行时可调用包装器,非托管资源内存分配,Marshal.ReleaseComObject(),Marshal.FinalReleaseComObject()等中可以找到的所有内容.它们都没有解释为什么应用程序要保留当相应的RCW符合垃圾回收条件时,在非托管堆中实时COM对象.

在一些文章中,我看到了C#中垃圾收集器的实际实现可能涉及优化的可能性,例如不执行特定代中所有符合条件的对象的收集.如果这个或类似的东西是真的,它可以解释为什么没有收集和销毁符合条件的RCW及其相应的COM对象.另一种解释可能是,非托管堆中的COM对象的销毁不直接与其相应RCW的集合相关联.我没有找到任何提供有关如何在.NET中处理COM对象的详细程度的内容.我需要更好地理解这一点,因为我的应用程序的内存使用量目前是不可接受的.任何指针或建议将不胜感激.

编辑:我应该补充一点,我非常熟悉终结器(RCW上没有记录)和IDisposable接口(RCW没有实现).据我所知,Marshal.ReleaseComObject()是显式"处理"COM引用的正确方法.我小心地在我的应用程序中为每个已知的COM对象用法添加该语句,这导致内存使用没有差别.

此外,当添加显式GC.Collect()导致没有内存问题时,不清楚为什么缺少处理或终止代码可能是问题.Dispose()和终结器的存在都不会导致实际的对象集合.前者允许对象抑制其最终化步骤(如果有的话),后者允许清除未在RCW中暴露的非托管资源.

c# com memory-management

5
推荐指数
1
解决办法
239
查看次数

带有本机和托管项目引用的项目的MSBuild

我有一个包含数百个C ++和C#项目的解决方案。我不能使用MSBuild直接构建具有不同类型项目依赖项的任何单个项目,因为有效配置(Deubg / Release)和平台(Win32 / AnyCPU / x64)设置对于不同项目类型是不同的。

例如,如果我有一个C ++项目“ CppProj1”依赖于C#项目“ CsharpProj1”,则我无法通过在命令行上指定Release / AnyCPU来使用MSBuild编译CppProj1,因为CppProj1无法在未知平台类型上进行编译。同样,指定Release / Win32将导致CsharpProj1编译失败。Visual Studio通过在每个解决方案文件中存储配置/平台设置的映射来解决此问题,但是使用MSBuild的巨大动机是将构建过程与Visual Studio IDE分离。有没有不使用VS解决方案文件就可以解决此问题的方法?

msbuild visual-studio

5
推荐指数
1
解决办法
1935
查看次数

如何在C#中确定SQL Server数据库列是否为自动增量?

我需要能够从DbConnection.GetSchema()返回的DataTable中确定SQL Server表中的特定列是否为identity / auto-increment。我不能直接查询系统表。

奇怪的是,如果我通过ODBC连接到SQL Server,则该列的返回数据类型将作为“ int身份”(或“ bigint身份”等)返回,但是如果我使用本机SQL Server驱动程序,则似乎没有“ int”列和“ int identity”列之间的区别。我还有其他方法可以推断出这些信息吗?

c# sql-server

4
推荐指数
2
解决办法
4068
查看次数

SQLite中的公用表表达式功能

我需要将两个连续的聚合函数应用于数据集(一系列平均值的总和),这可以通过SQL Server中的公共表表达式或支持CTE的其他DBMS轻松地例行完成.不幸的是,我目前仍然坚持使用不支持CTE的SQLite.是否有替代或解决方法在SQLite中实现相同的结果而不执行两个查询并在代码中汇总结果?

为了添加更多细节,我不认为可以通过视图轻松完成,因为需要根据带有多个参数的WHERE子句检索第一组聚合值.例如,

SELECT avg(elapsedTime)
FROM statisticsTable
WHERE connectionId in ([lots of values]) AND 
      updateTime > [startTime] AND
      updateTime < [endTime]
GROUP BY connectionId
Run Code Online (Sandbox Code Playgroud)

然后我需要这些平均值的总和.

sqlite common-table-expression

2
推荐指数
1
解决办法
5196
查看次数

将聚合函数应用于另一个聚合函数的SQL查询

我有几个查询结果使用一个或多个聚合函数和日期GROUP-BY,所以他们看起来像这样:

Date     VisitCount(COUNT)  TotalBilling(SUM)
1/1/10     234                15765.21
1/2/10     321                23146.27
1/3/10     289                19436.51

上面简化的SQL是:

SELECT 
  VisitDate, 
  COUNT(*) AS VisitCount, 
  SUM(BilledAmount) AS TotalBilling 

FROM Visits 

GROUP BY VisitDate
Run Code Online (Sandbox Code Playgroud)

我想要的是一种将聚合函数(如AVG)应用于结果集中的一列的方法.例如,我想将"AvgVisits"和"AvgBilling"列添加到结果集中,如下所示:

Date     VisitCount(COUNT)  TotalBilling(SUM)  AvgVisits  AvgBilling
1/1/10     234                15765.21          281.3      19449.33
1/2/10     321                23146.27          281.3      19449.33
1/3/10     289                19436.51          281.3      19449.33

SQL不允许将聚合函数应用于另一个聚合函数或子查询,因此我能想到的唯一方法是使用临时表或迭代结果集并手动计算值.有没有办法在没有临时表或手动计算的情况下在MSSQL2008中执行此操作?

sql-server aggregate-functions sql-server-2008

1
推荐指数
1
解决办法
2480
查看次数