dedlfix: C# - 2 DataTable vergleichen

Beitrag lesen

Tach!

folgendes sollte möglich sein

.Where(

values => strArray.Any(name => !values.Row1[name].Equals(values.Row2[name]))
);

  
Ist es auch, zum meinem Erstauen. Da bei einem MS-SQL Server als Datenhaltung die Expression in ein SQL-Statement übersetzt wird, sind nicht alle LINQ-Ausdrücke möglich. Der vorliegende kann aber offenbar übersetzt werden. Das Resultat ist jedoch nicht sehr ansehnlich.  
  
Mit  
  
  `string[] items = new string[] { "Workitem 2", "Workitem 3" };`{:.language-c}  
  
liefert ein  
  
  `.Where(t => items.Any(i => i == t.Description))`{:.language-c}  
  
dieses Monster  
  
~~~sql
SELECT  
[Extent1].[Id] AS [Id],  
[Extent1].[Description] AS [Description]  
FROM [dbo].[TimeCards] AS [Extent1]  
WHERE  EXISTS (SELECT  
	1 AS [C1]  
	FROM  (SELECT  
		N'Test 1' AS [C1]  
		FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]  
	UNION ALL  
		SELECT  
		N'Test 2' AS [C1]  
		FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]  
	WHERE [UnionAll1].[C1] = [Extent1].[Description]  
)

Zum Vergleich dazu ergibt ein

.Where(t => t.Description == "Test 1" || t.Description == "Test 2")

ein übersichtliches

SELECT  
[Extent1].[Id] AS [Id],  
[Extent1].[Description] AS [Description]  
FROM [dbo].[Tabelle] AS [Extent1]  
WHERE [Extent1].[Description] IN (N'Test 1',N'Test 2')

Die Frage ist nun, was kostet mehr, die komplexe Query der Any-Variante oder das Erstellen eines Expression-Trees für die ||-Variante.

P.S: Die zweite Where-Version ließ sich nur mit festen Strings notieren, items[0] und items [1] stattdessen zu verwenden, lässt der LINQ-to-Entities-Mechanismus nicht zu (siehe oben). Beim Zusammenbau eines Expression-Trees stellt das aber kein Problem dar, weil man da einer ConstantExpression mit Typ String einen Wert aus beliebiger Quelle übergeben kann. Und so sähe solch ein Expression-Tree für die zweite Where-Variante aus. Bei mehr Werten müssen entsprechende Equal und verschachtelte OrElse erzeugt werden.

ParameterExpression paramT = Expression.Parameter(typeof(Tabelle), "t");  
MemberExpression desc = Expression.PropertyOrField(paramT, "Description");  
BinaryExpression one = Expression.Equal(desc, Expression.Constant(items[0], typeof(string)));  
BinaryExpression two = Expression.Equal(desc, Expression.Constant(items[1], typeof(string)));  
BinaryExpression or = Expression.OrElse(one, two);  
Expression<Func<Tabelle, bool>> where = Expression.Lambda<Func<Tabelle, bool>>(or, paramT);

dedlfix.