Bei dem Versuch, zu lösen:Temporäre Tabellen in Linq - Jeder sieht ein Problem damit?
Linq .Contains with large set causes TDS error
Ich glaube, ich auf einer Lösung gestolpert, und ich würde gerne sehen, ob es das Problem der Annäherung an einem koscheren Weg.
(kurze Zusammenfassung) Ich möchte Linq-Join gegen eine Liste von Record-IDs, die nicht (vollständig oder zumindest leicht) in SQL generiert werden. Es ist eine große Liste und bläst häufig über die Grenze von 2100 Artikeln für den TDS-RPC-Aufruf. Was ich also in SQL getan hätte, würde sie in eine temporäre Tabelle werfen und dann gegen sie, wenn ich sie brauchte.
So machte ich das gleiche in Linq.
In meiner MyDB.dbml Datei, die ich hinzugefügt:
<Table Name="#temptab" Member="TempTabs">
<Type Name="TempTab">
<Column Name="recno" Type="System.Int32" DbType="Int NOT NULL"
IsPrimaryKey="true" CanBeNull="false" />
</Type>
</Table>
die Designer öffnen und schließen sie die erforderlichen Einträge dort hinzugefügt, obwohl für die Vollständigkeit, die ich von der MyDB.desginer.cs Datei zitieren werde:
[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));
}
}
}
Dann wurde es einfach eine Sache des Jonglierens um einige Dinge im Code. Wo würde ich normalerweise gehabt haben:
MyDBDataContext mydb = new MyDBDataContext();
ich es bekommen hatte seine Verbindung mit einem normalen SqlConnection zu teilen, so dass ich die Verbindung verwenden, könnte die temporäre Tabelle zu erstellen. Danach scheint es ziemlich brauchbar.
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();
und deren Verwendung:
// 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;
Sieht jemand ein Problem mit diesem Ansatz als Allzwecklösung für die Verwendung von temporären Tabellen in in Linq verbindet?
Es löste mein Problem wunderbar, da ich jetzt eine direkte Verbindung in Linq machen kann, anstatt .Contains() zu verwenden.
Postscript: Das einzige Problem, das ich habe, ist, dass auf dem Tisch Linq und regelmäßige SqlCommands Mischen (wo man Lesen/Schreiben und so das andere ist) kann gefährlich sein. Immer mit SqlCommands in die Tabelle einfügen, und dann Linq-Befehle zum Lesen es funktioniert gut. Anscheinend speichert Linq Ergebnisse - es gibt wahrscheinlich einen Weg, aber es war nicht offensichtlich.
Um ehrlich zu sein, habe ich nicht die Lösung getestet, die ich mit temporären Tabellen bereitgestellt habe. Davon abgesehen wird die Lösung definitiv mit "permanenten" Tabellen funktionieren. Der Grund, warum ich die DataContext.ExecuteCommand() -Methode verwende, liegt auch daran, dass die SQL-Anweisung von der LINQ-Engine überhaupt nicht verarbeitet wird. Was Sie senden, ist, was ausgeführt wird. –