【发布时间】:2016-10-21 13:22:48
【问题描述】:
假设我们有 2 个表,TableA 和 TableB,它们之间存在 PK-FK 关系,我已经写了一个 extension method 到 join 这两个表并获取数据。这种扩展方法非常具体,可以为这两张表完成工作。
需要做些什么来创建一个 GENERIC 扩展方法来连接任意两个表并投影数据?
我的代码:
TableA 的架构:
CREATE TABLE [dbo].[TableA](
[Id_1] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[Address] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED
(
[Id_1] ASC
)
TableB 的架构:
CREATE TABLE [dbo].[TableB](
[Id_2] [int] IDENTITY(1,1) NOT NULL,
[Name2] [nvarchar](max) NULL,
[Address2] [nvarchar](max) NULL,
[FK_Id] [int] NULL,
PRIMARY KEY CLUSTERED
(
[Id_2] ASC
)
ALTER TABLE [dbo].[TableB] WITH CHECK ADD FOREIGN KEY([FK_Id])
REFERENCES [dbo].[TableA] ([Id_1])
C#代码:
public class ABDTO
{
public TableA A { get; set; }
public TableB B { get; set; }
}
public static class Helper
{
public static IEnumerable<ABDTO> Join(this IEnumerable<TableA> tableA,IEnumerable<TableB> tableB)
{
return tableA.Join(tableB,x => x.Id_1,y => y.FK_Id,
(x, y) =>new ABDTO
{
A = x,
B = y
});
}
public class Program
{
static void Main(string[] args)
{
Operation1();
Console.ReadLine();
}
public static void Operation1()
{
using (var db = new SampleEntities())
{
var result = db.TableAs.Join(db.TableBs);
foreach(var item in result)
{
Console.WriteLine("{0}; {1} ||| {2} ; {3}", item.A.Id_1, item.A.Name, item.B.Id_2, item.B.Name2);
}
}
}
}
所以,Join() 是一个extension method,它接受TableA 和TableB,在PK-FK 关系上加入它们并投射出选择器。
我怎样才能将generic 写成:
public static IEnumerable<T> Join(this IEnumerable<T> Ta, IEnumerable<T> Tb)
{
return Ta.Join(Tb, x => Ta.SomeColumn1, y => Tb.SomeColumn2,
(x, y) => Projection of columns);
}
LINQ和Extension methods我不是很擅长,请帮忙。
任何指针也会有所帮助。
【问题讨论】:
-
您是否尝试接受列名作为参数?如果您将 Func 委托作为“加入”方法的参数。从调用代码中,您可以提供要用于加入的列,因此无需在“加入”扩展中硬编码。
-
@SIva Gopal...我没听懂你的意思..你能解释一下吗?
-
您似乎正在寻找一种自动发现“可连接”列的方法。问题是:任何自动化程序如何知道您想加入什么?仅按名称约定(同名)?
-
扩展方法对
Join本身的改进如何?似乎您缺少连接条件参数和结果定义,但添加这些参数可以有效地为您提供与Join相同的语法,所以我不确定您要进行哪些改进。 -
你真的不应该在内存中执行这个连接;您应该在数据库中执行此连接。
标签: c# linq generics join extension-methods