我有一个MS SQL Server 2005数据库.在一些过程中,我将表参数作为nvarchar(以逗号分隔)传递给存储过程,并在内部划分为单个值.我将它添加到SQL命令参数列表中,如下所示:
cmd.Parameters.Add("@Logins", SqlDbType.NVarchar).Value = "jim18,jenny1975,cosmo";
Run Code Online (Sandbox Code Playgroud)
我必须将数据库迁移到SQL Server 2008.我知道有表值参数,我知道如何在存储过程中使用它们.但我不知道如何将一个传递给SQL命令中的参数列表.有谁知道Parameters.Add程序的正确语法?或者是否有另一种传递此参数的方法?
c# sql-server stored-procedures sqlcommand table-valued-parameters
我试图将数组参数传递给C#中的SQL commnd,如下所示,但它不起作用.有没有人见过它?
string sqlCommand = "SELECT * from TableA WHERE Age IN (@Age)";
SqlConnection sqlCon = new SqlConnection(connectString);
SqlCommand sqlComm = new SqlCommand();
sqlComm.Connection = sqlCon;
sqlComm.CommandType = System.Data.CommandType.Text;
sqlComm.CommandText = sqlCommand;
sqlComm.CommandTimeout = 300;
sqlComm.Parameters.Add("@Age", SqlDbType.NVarChar);
StringBuilder sb = new StringBuilder();
foreach (ListItem item in ddlAge.Items)
{
if (item.Selected)
{
sb.Append(item.Text + ",");
}
}
sqlComm.Parameters["@Age"].Value = sb.ToString().TrimEnd(',');
Run Code Online (Sandbox Code Playgroud) 我希望能够使用使用表值参数的实体框架构建参数化的临时 SQL 查询。
注意:引起我兴趣的用例是在给定 ID 列表的情况下查询多个实体。我希望查询计划程序能够在可能的情况下缓存计划,但我不一定要创建存储过程。
假设我有一些 id:
IEnumerable<int> ids = new [] {0, 42, -1};
Run Code Online (Sandbox Code Playgroud)
如果我编写一个 EF 查询,例如
context.MyEntities
.Where(e => ids.Contains(e.Id))
Run Code Online (Sandbox Code Playgroud)
生成的 sql未参数化,如下所示:
SELECT
[Extent1].[Name] AS [Name]
FROM [MyEntities] AS [Extent1]
WHERE [Extent1].[Id] IN (0, 42, -1)
Run Code Online (Sandbox Code Playgroud)
我想要得到的是类似的东西
SELECT
[Extent1].[Name] AS [Name]
FROM [MyEntities] AS [Extent1]
WHERE EXISTS (SELECT
1
FROM @ids AS [Extent2]
WHERE [Extent2].[Id] = [Extent1].[Id]
)
Run Code Online (Sandbox Code Playgroud)
这是完全参数化的。
这可以在 EF 即席查询中完成吗?
我知道可以使用EF 传递表值参数来直接查询(例如存储过程),使用 withSqlParameter和SqlDbType.StructuredaDataTable作为其值(请参阅/sf/answers/728679731/) …
我正在使用这个库来批量执行批量删除,如下所示:
while (castedEndedItems.Any())
{
var subList = castedEndedItems.Take(4000).ToList();
DBRetry.Do(() => EFBatchOperation.For(ctx, ctx.SearchedUserItems).Where(r => subList.Any(a => a == r.ItemID)).Delete(), TimeSpan.FromSeconds(2));
castedEndedItems.RemoveRange(0, subList.Count);
Console.WriteLine("Completed a batch of ended items");
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我一次删除了一批 4000 个项目,并将它们作为参数传递给查询...
我正在使用这个库来执行批量删除:
https://github.com/MikaelEliasson/EntityFramework.Utilities
Run Code Online (Sandbox Code Playgroud)
然而,这样的性能绝对是糟糕的......我测试了几次应用程序并删除了 80000 条记录,例如需要 40 分钟!?
我应该注意,我要删除的参数 (ItemID) 是 varchar(400) 类型,并且出于性能原因对其进行了索引....
是否有任何其他库可以使用或调整此查询以使其工作得更快,因为目前的性能绝对糟糕..:/
我需要以下查询:
createList(string commaSeparatedElements) {
...
SqlCommand query = new SqlCommand("SELECT * FROM table WHERE id IN ("+commaSeparatedElements+")");
...
}
Run Code Online (Sandbox Code Playgroud)
我想使用参数化查询来编写它,因此检查字符串中的每个元素以防止Sql-Injections.
伪代码:
createList(string commaSeparatedElements) {
...
SqlParameterList elements = new SqlParameterList("@elements", SqlDbType.Int);
SqlParameterList.Values = commaSeparatedElements.split(new Char[1] {','});
SqlCommand query = new SqlCommand("SELECT * FROM table WHERE id IN (@elements)");
query.Parameters.Add(elements);
...
}
Run Code Online (Sandbox Code Playgroud)
C#中是否存在类似的内容,或者我必须自己编写?
编辑:谢谢你的所有答案.当我尽量不使用代码时,我不理解(在过去的日子里有太多不好的经历),精巧和表值参数,即使它们可能完全满足我的需求,也是禁止的.我刚做了一个循环.
string[] elements = commaSeparatedElements.split(new Char[1] {','});
StringList idParamList = new StringList();
for(int i=0;i<elements.Count;i++) {
query.Parameters.AddWithValue("@element"+i,Convert.ToInt32(elements[i]));
idParamList.Add("@element" + i);
}
SqlCommand query = new SqlCommand("SELECT * FROM table …Run Code Online (Sandbox Code Playgroud) 使用 TypeAccessor.Create FastMember 时似乎总是返回按字母顺序排序的列列表。是否可以告诉它保留类中列的顺序?
例如:
var testClass = new { B = "1", A = "2" };
Run Code Online (Sandbox Code Playgroud)
将从 GetMembers 返回 A 列,然后返回 B 列,如果可能的话,我想让它保留 B 列然后 A 的顺序。
问题:我在 SQL Server 数据库上使用 SQLMetal 生成了一个 DataContext。数据库有 TableA,其中包含具有 Int64 标识符的实体。我的查询需要处理查询某个集合中具有 ID 的所有元素的情况。随着数据集的增长,该集偶尔包含超过 2100 个 ID。
我意识到这个问题与有关该主题的其他问题类似,但我正在寻求帮助构建扩展方法来解决该问题。
相关问题:
避免 LINQ to SQL 中的 2100 个参数限制
使用 Contains() 时达到 2100 个参数限制 (SQL Server)
我的代码看起来像这样:
var ids = new List<long>{ 1, 2, 3, /*...,*/ 2101};
var database = new MyDatabaseClass(connection)
var items = database
.TableA
.Where(x=>ids.Contains(x.RecordID))
.ToList();
Run Code Online (Sandbox Code Playgroud)
并产生此错误:
传入的表格数据流 (TDS) 远程过程调用 (RPC) 协议流不正确。此 RPC 请求中提供了太多参数。最大值为 2100。
随着各种数据集的增长,我预计会经常遇到这个问题,并且我想创建一个可用于任何表的通用扩展。其想法是将查询分解为更小的Where Contains 查询,然后聚合结果。这是我试图展示我的想法的尝试之一:
public static List<TSource> WhereMemberInUniverse<TSource, TUniverse>(this IQueryable<TSource> source, Func<TSource, TUniverse> memberSelector, IEnumerable<TUniverse> universe)
{
var …Run Code Online (Sandbox Code Playgroud) c# ×7
sql-server ×4
sql ×2
asp.net ×1
asp.net-mvc ×1
bulk ×1
bulk-delete ×1
fastmember ×1
linq ×1
linq-to-sql ×1
reflection ×1
sqlcommand ×1
t-sql ×1