我已根据一个公共列创建了一个通用extension
方法来加入2 tables
。代码如下:
public class SomeDTO<T,U>
{
public T TableA { get; set; }
public U TableB { get; set; }
}
public static class Helper
{
public static IQueryable<SomeDTO<T,U>> JoinExtension<T,U,Key>(this IQueryable<T> tableA, IQueryable<U> tableB, Expression<Func<T,Key>> columnA, Expression<Func<U,Key>> columnB)
{
return tableA.Join(tableB, columnA, columnB,(x, y) => new SomeDTO<T, U>{TableA = x,TableB = y});
}
}
现在database
中的表有2个公共列(Id,Type),我需要编写一个公共扩展方法,根据2个常用列连接这些表,写一下如下:
public static IQueryable<SomeDTO<T, U>> JoinExtensionTwoColumns<T, U, Key>(this IQueryable<T> tableA, IQueryable<U> tableB, Expression<Func<T, Key>> columnA, Expression<Func<U, Key>> columnB, Expression<Func<T, Key>> columnC, Expression<Func<U, Key>> columnD)
{
return tableA.Join(tableB, a => new { columnA, columnB }, b => new { columnC, columnD }, (a, b) => new SomeDTO<T, U> { TableA = a, TableB = b });
}
编译器在代码行tableA.Join
中给出了如下所示的错误....如下所示:
The type arguments for method 'Queryable.Join<TOuter, TInner, TKey, TResult>(IQueryable<TOuter>, IEnumerable<TInner>, Expression<Func<TOuter, TKey>>, Expression<Func<TInner, TKey>>, Expression<Func<TOuter, TInner, TResult>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
它无法正确理解arguments
及其性质。
指向我可能出错的地方?
修改
我现在有一个成功编译的方法,但是我得到了一个运行时错误
&#34; The LINQ expression node type 'Lambda' is not supported in LINQ to Entities.
&#34;
public static IQueryable<SomeDTO<T, U>> JoinExtensionTwoColumns<T, U, Key>(this IQueryable<T> tableA, IQueryable<U> tableB, Expression<Func<T, Key>> columnA, Expression<Func<U, Key>> columnB, Expression<Func<T, Key>> columnC, Expression<Func<U, Key>> columnD)
{
return tableA.Join(tableB, a => new object[]{ columnA, columnB }, b => new object []{ columnC, columnD }, (a, b) => new SomeDTO<T, U> { TableA = a, TableB = b });
}
如此调用方法:
var result= (db.table1.JoinExtensionTwoColumns<table1,table2,int>(db.table2, c => c.id.ToString(), d => d.id.ToString(),e => e.type, f => f.type)).Take(10);
还有更多指示。
答案 0 :(得分:3)
您已完成所有工作:不需要JoinExtensionTwoColumns
方法,您可以使用JoinExtension
根据多个列加入表格:
tableA.JoinExtension<TypeA, TypeB, object>(tableB, x => new { x.column1, x.column2 },
x => new { column1 = x.column2, column2 = x.column3 });
但是在这种情况下 - 由于第三个任意 - object
类型参数,解决方案不是TypeSafely ,要修复它,您可以通过以下方式重构以前的解决方案:
public static class Helper
{
public class JoinCondition<TFirst, TSecond>
{
public TFirst column1 { get; set; }
public TSecond column2 { get; set; }
}
public static IQueryable<SomeDTO<T, U>> JoinExtension<T, U, TFirst, TSecond>(this IQueryable<T> tableA, IQueryable<U> tableB,
Expression<Func<T, JoinCondition<TFirst, TSecond>>> joinSelectorA,
Expression<Func<U, JoinCondition<TFirst, TSecond>>> joinSelectorB)
{
return tableA.Join(tableB, joinSelectorA, joinSelectorB, (x, y) => new SomeDTO<T, U> { TableA = x, TableB = y });
}
}
<强> Implementaion:强>
var answer = context.TableA.JoinExtension(context.TableB,
x => new Helper.JoinCondition<int, string> { column1 = x.prop1, column2 = x.prop2},
x => new Helper.JoinCondition<int, string> { column1 = x.prop3, column2 = x.prop4}
).ToList();
P.S。
JoinExtensionTwoColumns
方法包含错误:您使用 columnA,columnB等作为列,但它们是谓词,你可以 以这种方式修复它(它在EF上下文不起作用):
public static IQueryable<SomeDTO<T, U>> JoinExtensionTwoColumns<T, U, Key>(this IQueryable<T> tableA, IQueryable<U> tableB,
Expression<Func<T, Key>> columnA, Expression<Func<U, Key>> columnB,
Expression<Func<T, Key>> columnC, Expression<Func<U, Key>> columnD)
{
return tableA.Join(tableB,
a => new { column1 = columnA.Compile()(a), column2 = columnC.Compile()(a) },
b => new { column1 = columnB.Compile()(b), column2 = columnD.Compile()(b) },
(a, b) => new SomeDTO<T, U> { TableA = a, TableB = b });
}