通用自定义连接扩展方法

时间:2016-06-20 10:18:31

标签: c# linq generics join extension-methods

假设我们有2个表,TableATableB,其中包含PK-FK关系,我已经写了extension methodjoin这两个表并获取数据。这种扩展方法非常具体,可以完成这两个表的工作。

创建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,它接收TableATableB,将它们加入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);
        }

LINQExtension methods我不是很好,请帮忙。 任何指针也会有所帮助。

1 个答案:

答案 0 :(得分:0)

我做了一些R&amp; D并且能够推断出解决方案。

public class ABDTO<T,U> 
    {
        public T A { get; set; }
        public U B { get; set; }
    }
    public static class Helper
    {
        public static IQueryable<ABDTO<T,U>> JoinEx<T,U,Key>(this IQueryable<T> tableA,IQueryable<U> tableB, Expression<Func<T, Key>> column1, Expression<Func<U, Key>> column2)
        {
            return tableA.Join(tableB, column1, column2, (y, z) => new ABDTO<T,U> {A= y, B=z });
        }
    }

JoinEx<>()是一种通用extension方法,它接收2个TU类型的表,在2列的基础上加入它们,并预测结果在一些常见的DTO

如下所示:

using (var db = new SampleEntities())
            {
                var result=db.TableAs.JoinEx<TableA, TableB, int>(db.TableBs, x => x.Id_1, y => y.FK_Id);  
                foreach(var item in result)
                {               
                        Console.WriteLine("{0} \t {1}",item.A.Name,item.B.Name2);                                       
                }
            }

我理解可能存在性能限制,并且这些操作必须在database中作为stored procedure执行,但这类通用内容还需要。

由于