在LINQ to SQL中避免2100参数限制
在我正在进行的项目中,我需要以下列方式访问LINQ中的2个数据库:
-
我得到了DB1指定日期范围之间的所有旅行号码列表,并将其存储为“长”值列表
-
我在DB2上执行了大量连接的广泛查询,但只查看上面列表中包含其旅行编号的旅行。
问题是,来自DB1的行程列表经常返回超过2100项 – 我当然在SQL中达到2100参数限制,这导致我的第二个查询失败。 我一直在寻找解决这个问题的方法,例如此处所描述的,但这实际上是将我的查询更改为LINQ-to-Objects,这会导致我的连接出现很多问题
我还能做其他解决方法吗?
因为LINQ-to-SQL可以调用存储过程,你可以
- 有一个存储过程,它将一个数组作为输入,然后将值放在临时表中以加入
- 同样通过采用存储过程分裂的字符串
或者自己将所有值上传到临时表并加入该表。
不过,也许您应该重新考虑这个问题:
- 可以将Sql server配置为允许查询其他数据库(包括oracle)中的表,如果允许,这可能是您的选项。
- 您是否可以使用某些复制系统来保持DB2中的行程编号表更新?
不确定这是否会有所帮助,但我在LinqPad中编写的一次性查询遇到了类似的问题,并最终定义并使用了这样的临时表。
[Table(Name="#TmpTable1")] public class TmpRecord { [Column(DbType="Int", IsPrimaryKey=true, UpdateCheck=UpdateCheck.Never)] public int? Value { get; set; } } public Table TmpRecords { get { return base.GetTable (); } } public void DropTable() { ExecuteCommand( "DROP TABLE " + Mapping.GetTable(typeof(T)).TableName ); } public void CreateTable () { 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 ids = .... this.Connection.Open(); // Note, if the connection is not opened here, the temporary table // will be created but then dropped immediately. CreateTable(); 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 (); this.Connection.Close();
}
在我的例子中,临时表只有一个int列,但是你应该能够定义你想要的任何列类型(只要你有一个主键)。
您可以拆分查询或使用填充了database1结果的database2中的临时表。