避免LINQ to SQL中的2100参数限制



在我目前正在进行的一个项目中,我需要以以下方式访问LINQ中的两个数据库:

  1. 我从DB1中获取指定日期范围内的所有行程编号的列表,并将其存储为"长"值列表

  2. 我在DB2上执行了一个包含大量联接的广泛查询,但只查看上面列表中包含其行程号的行程。

问题是,来自DB1的trip列表通常返回超过2100个项目——当然,我在SQL中达到了2100个参数的限制,这导致我的第二个查询失败。我一直在寻找解决这个问题的方法,比如这里所描述的,但这实际上会将我的查询更改为LINQ to Objects,这会导致我的加入出现很多问题

我还有其他解决办法吗?

由于LINQ to SQL可以调用存储的proc,因此可以使用

  • 有一个存储的proc,它将数组作为输入,然后将值放入临时表中进行联接
  • 同样,通过获取存储的proc拆分的字符串

或者自己将所有值上传到一个临时表并加入该表。

然而,也许你应该重新思考这个问题:

  • Sql服务器可以配置为允许对其他数据库(包括oracle)中的表进行查询,如果允许,这可能是您的一个选项
  • 您是否可以使用某种复制系统在DB2中更新行程号表

不确定这是否会有所帮助,但我在LinqPad中编写的一个一次性查询也遇到了类似的问题,最终定义并使用了这样的临时表。

[Table(Name="#TmpTable1")]
public class TmpRecord
{
    [Column(DbType="Int", IsPrimaryKey=true, UpdateCheck=UpdateCheck.Never)]
    public int? Value { get; set; }         
}
public Table<TmpRecord> TmpRecords
{
    get { return base.GetTable<TmpRecord>(); }
}
public void DropTable<T>()
{
    ExecuteCommand( "DROP TABLE " + Mapping.GetTable(typeof(T)).TableName  );
}
public void CreateTable<T>()
{
   ExecuteCommand(
    typeof(DataContext)
    .Assembly
    .GetType("System.Data.Linq.SqlClient.SqlBuilder")
    .InvokeMember("GetCreateTableCommand", 
      BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod
     , null, null, new[] { Mapping.GetTable(typeof(T)) } ) as string
    );      
}

用法有点像

void Main()
{
    List<int> ids = .... 
    this.Connection.Open();
    // Note, if the connection is not opened here, the temporary table  
    // will be created but then dropped immediately.
    CreateTable<TmpRecord>();    
    foreach(var id in ids)
        TmpRecords.InsertOnSubmit( new TmpRecord() { Value = id}) ;
    SubmitChanges();
    var list1 = (from r in CustomerTransaction 
        join tt in TmpRecords on r.CustomerID equals tt.Value 
        where ....
        select r).ToList();
     DropTable<TmpRecord>();    
     this.Connection.Close();    

}

在我的例子中,临时表只有一个int列,但您应该能够定义您想要的任何列类型(只要您有主键)。

您可以拆分查询,或者在数据库2中使用一个临时表,该表由数据库1中的结果填充。

相关内容

  • 没有找到相关文章

最新更新