Linq Join

1.准备数据源,我这边定义了一个实体,里面包含ID,Name,State

 public class NameModel
        {
            public int Id { get; set; }

            public string Name { get; set; }

            public string State { get; set; }
        }
List<NameModel> leftName = new List<NameModel>()
            {
                new NameModel() {Id=1,Name="我是1",State="4" },
                new NameModel() {Id=2,Name="我是2",State="4" },
                new NameModel() {Id=3,Name="我是3",State="4" },
                new NameModel() {Id=4,Name="我是4",State="4" },
                new NameModel() {Id=0,Name="我是新人",State="4" },
                new NameModel() {Id=0,Name="我是新人",State="4" }
            };

            List<NameModel> rigthName = new List<NameModel>(){
                new NameModel() {Id=1,Name="我是r1",State="4" },
                new NameModel() {Id=5,Name="我是R5",State="4" },
                new NameModel() {Id=3,Name="我是R3",State="4" },
                new NameModel() {Id=7,Name="我是R7",State="4" }
            };

2.我们来看看将2个集合通过Linq 来个内连接,这边通过2种方式来实现:

var list = from left in leftName
                       join rigth in rigthName on left.Id equals rigth.Id
                       select new
                       {
                           LeftID = left.Id,
                           LeftName = left.Name,
                           RigthID = rigth.Id,
                           RigthName = rigth.Name
                       };
            foreach (var l in list)
            {
                Console.WriteLine(
                        l.LeftID + "\t\t" +
                        l.LeftName + "\t\t" +
                        l.RigthID + "\t\t" +
                        l.RigthName + "\t\t"
                        );
            }
            Console.ReadKey();
var list = leftName.Join(rigthName, p => p.Id, x => x.Id, (p, x) => new
            {
                LeftID = p.Id,
                LeftName = p.Name,
                RigthID = x.Id,
                RigthName = x.Name
            });
            foreach (var l in list)
            {
                Console.WriteLine(
                        l.LeftID + "\t\t" +
                        l.LeftName + "\t\t" +
                        l.RigthID + "\t\t" +
                        l.RigthName + "\t\t"
                        );
            }
            Console.ReadKey();

二次运行的结果是一样的,如图

大家都知道链接包含内连和外连,外连又包含了左右连接,那么我们如何通过Linq来实现左右连接呢?这边就需要我们自己去写扩展方法来实现:

这边需要去定义扩展方法:

public static class JoinExtensions
    {
        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TInner"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="inner"></param>
        /// <param name="pk"></param>
        /// <param name="fk"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static IEnumerable<TResult> LeftJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
                                                                                        IEnumerable<TInner> inner,
                                                                                        Func<TSource, TKey> pk,
                                                                                        Func<TInner, TKey> fk,
                                                                                        Func<TSource, TInner, TResult> result)
        {
            IEnumerable<TResult> _result = Enumerable.Empty<TResult>();

            _result = from s in source
                      join i in inner
                      on pk(s) equals fk(i) into joinData
                      from left in joinData.DefaultIfEmpty()
                      select result(s, left);

            return _result;
        }

        /// <summary>
        /// 右连接
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TInner"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="inner"></param>
        /// <param name="pk"></param>
        /// <param name="fk"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static IEnumerable<TResult> RightJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
                                                                                         IEnumerable<TInner> inner,
                                                                                         Func<TSource, TKey> pk,
                                                                                         Func<TInner, TKey> fk,
                                                                                         Func<TSource, TInner, TResult> result)
        {
            IEnumerable<TResult> _result = Enumerable.Empty<TResult>();

            _result = from i in inner
                      join s in source
                      on fk(i) equals pk(s) into joinData
                      from right in joinData.DefaultIfEmpty()
                      select result(right, i);

            return _result;
        }

        /// <summary>
        /// 合并
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TInner"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="inner"></param>
        /// <param name="pk"></param>
        /// <param name="fk"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static IEnumerable<TResult> FullOuterJoinJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
                                                                                         IEnumerable<TInner> inner,
                                                                                         Func<TSource, TKey> pk,
                                                                                         Func<TInner, TKey> fk,
                                                                                         Func<TSource, TInner, TResult> result)
        {

            var left = source.LeftJoin(inner, pk, fk, result).ToList();
            var right = source.RightJoin(inner, pk, fk, result).ToList();

            return left.Union(right);

        }
    }

下面我们就实现下左链接:

var list = leftName.LeftJoin(rigthName, p => p.Id, x => x.Id, (p, x) => new
            {
                LeftID = p.Id,
                LeftName = p.Name,
                RigthID = x == null ? 0 : x.Id,
                RigthName = x == null ? "" : x.Name
            });
            foreach (var l in list)
            {
                Console.WriteLine(
                        l.LeftID + "\t\t" +
                        l.LeftName + "\t\t" +
                        l.RigthID + "\t\t" +
                        l.RigthName + "\t\t"
                        );
            }
            Console.ReadKey();

时间: 2024-10-24 20:19:43

Linq Join的相关文章

Linq join on 多条件

var a = from m in DbContext.Set<T1>() join q in DbContext.Set<T2>() on new { m.ID, Phone=m.Phone1 } equals new { q.ID, Phone=q.Phone2 } where m.Phone1 !=null select new { m.ID, m.Phone1 }; a = a.OrderBy(m => m.Phone1).Skip(2).Take(2); SELEC

linq join一些忘记的操作

Linq之Join操作

1 摘要 文章通过一个简单的实例对Linq中的Join操作进行演示,并在文章的最后对Join操作相关知识点进行简单的总结. 2 实例演示 1) 新建数据库MyTestDB,在数据库中新建数据表tb_Class和tb_Student,两表的定义如下图所示.                                        图1  tb_Class的定义                                                                    

实战 EF(LINQ) 如何以子查询的形式来 Join

如题,大多数网上关于 LINQ Join 的示例都是以 from x in TableA  join ... 这样的形式,这种有好处,也有劣势,就是在比如我们使用的框架如果已经封装了很多方法,比如分页方法.而我们的业务方法只需要在 Service 层调用框架的分页方法,同时注入条件拼接的委托就可以了.而这时候,为了简单,就会以调用 Join() 方法来实现关联查询,外部看起来好像是子查询,而实际上 Entity Framework 生成 SQL 时,还是会以 Inner join 的形式来生成

LINQ Sample

Sample LINQ Queries: In this section, you will learn some complex LINQ queries. We will use the following Student and Standard collection for our queries. Sample Collections: IList<Student> studentList = new List<Student>() { new Student() { S

Working with LINQ to Entities &amp; LINQ to DataTable

Introduction Now a days, working with LINQ is an added advantage for any developer. We can write almost all types of queries when compared with SQL Server SQL querying. The important thing in LINQ is understanding the syntax and what it returns. Back

LINQ巩固

LINQ巩固 LINQ过滤运算符 Where 基于谓词函数过滤值 测试例子如下: public class TestModel { public string Name { get; set; } public string Age { get; set; } } List<TestModel> lst = new List<TestModel>() { new TestModel(){Name = "张三" }, new TestModel(){Name =

ERS遇到的问题及solution

1, js事件响应函数在firefox/safari中正确的设置 错误:a.onclick=function(){......}; 正确:a.setAttribute("onclick","...."); 2, VS中文件内容的批量替换 查找和替换中:勾选“正则表达式”选项 [示例: 替换onclick事件的绑定] onclick ={(.+)}(";)$ -----> setAttribute("onclick", \1&quo

Entity Framework: Joining in memory data with DbSet

转载自:https://ilmatte.wordpress.com/2013/01/06/entity-framework-joining-in-memory-data-with-dbset/ The argument of this post is relevant to people using Entity Framework and needing to filter data coming from a Database with a list of in-memory data. I