:Linqのテンポラリテーブル - 誰でもこれに問題がありますか?解決しようとして
Linq .Contains with large set causes TDS error
私は解決策に出くわしたと思う、と私はそれが問題にアプローチするコーシャー方法だかどうかを確認したいと思います。
(短い要約)SQLで生成された(完全にまたは少なくとも簡単に)レコードIDのリストに対してlinq-joinしたいと思います。これは大きなリストで、TDS RPC呼び出しの2100項目制限を超えて頻繁に吹いています。だから、私がSQLで行ったことは、一時テーブルでそれらをスローし、それを必要とするときにそれに参加しました。
私はLinqでも同じことをしました。私MyDB.dbmlファイルで
私が追加:
<Table Name="#temptab" Member="TempTabs">
<Type Name="TempTab">
<Column Name="recno" Type="System.Int32" DbType="Int NOT NULL"
IsPrimaryKey="true" CanBeNull="false" />
</Type>
</Table>
がデザイナーを開く万全を期すために、私はMyDB.desginer.csファイルから引用されますが、それは、そこに必要なエントリを追加閉じる:
[Table(Name="#temptab")]
public partial class TempTab : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _recno;
#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnrecnoChanging(int value);
partial void OnrecnoChanged();
#endregion
public TempTab()
{
OnCreated();
}
[Column(Storage="_recno", DbType="Int NOT NULL", IsPrimaryKey=true)]
public int recno
{
get
{
return this._recno;
}
set
{
if ((this._recno != value))
{
this.OnrecnoChanging(value);
this.SendPropertyChanging();
this._recno = value;
this.SendPropertyChanged("recno");
this.OnrecnoChanged();
}
}
}
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void SendPropertyChanging()
{
if ((this.PropertyChanging != null))
{
this.PropertyChanging(this, emptyChangingEventArgs);
}
}
protected virtual void SendPropertyChanged(String propertyName)
{
if ((this.PropertyChanged != null))
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
次に、コード内のいくつかのことを巡ってジャグリングすることになりました。どこで正常に持っていたと思います:
MyDBDataContext mydb = new MyDBDataContext();
私は一時テーブルを作成するために、接続を使用することができるように、それは通常のSqlConnectionオブジェクトとの接続を共有するために取得しなければなりませんでした。その後、それはかなり使えるようです。
string connstring = "Data Source.... etc..";
SqlConnection conn = new SqlConnection(connstring);
conn.Open();
SqlCommand cmd = new SqlCommand("create table #temptab " +
"(recno int primary key not null)", conn);
cmd.ExecuteNonQuery();
MyDBDataContext mydb = new MyDBDataContext(conn);
// Now insert some records (1 shown for example)
TempTab tt = new TempTab();
tt.recno = 1;
mydb.TempTabs.InsertOnSubmit(tt);
mydb.SubmitChanges();
そして、それを使用して:
// Through normal SqlCommands, etc...
cmd = new SqlCommand("select top 1 * from #temptab", conn);
Object o = cmd.ExecuteScalar();
// Or through Linq
var t = from tx in mydb.TempTabs
from v in mydb.v_BigTables
where tx.recno == v.recno
select tx;
誰のLINQに参加するには、一時テーブルを使用するための汎用的なソリューションとして、このアプローチの問題を参照してくださいしていますか?
私の問題をすばらしく解決しました。今はLinqで直接.Contains()を使う必要がなくなりました。
ポストスクリプト: 私が持っている一つの問題は、(1が書き込み/読み出しであるので、他がどこにあるか)、テーブルの上にLINQのと定期的SqlCommandsを混合することは危険であるということです。いつもSqlCommandsを使ってテーブルに挿入し、それを読むためのLinqコマンドはうまくいきます。どうやら、Linqは結果をキャッシュします。おそらく周りに道がありますが、それは明らかではありませんでした。
正直言って、私は一時テーブルを使って提供したソリューションをテストしていません。つまり、ソリューションは間違いなく "永久"テーブルを使用して動作します。また、DataContext.ExecuteCommand()メソッドを使用している理由は、LINQエンジンによってSQL文がまったく処理されないためです。送信するものが実行されるためです。 –