求一个linq的写法(join)

bearben2010 2011-07-13 01:56:46

public class Student
{
public String ID { get; set; }
public String StuName { get; set; }
}
public class Grade
{
public String ID { get; set; }
public String GrideName { get; set; }
}

//测试数据
List<Student> tempStuList = new List<Student>() {
new Student(){ ID="001001", StuName="a"},
new Student(){ ID="002001", StuName="b"},
new Student(){ ID="002001", StuName="c"},
new Student(){ ID="003001", StuName="d"},
new Student(){ ID="001001", StuName="e"},
};

List<Grade> tempGradeList = new List<Grade>() {
new Grade(){ ID="001", GrideName = "g1"},
new Grade(){ ID="002", GrideName = "g2"},
new Grade(){ ID="003", GrideName = "g3"},
};

说明一下:这里仅仅是讨论语法如何写,而不是讨论设计合理与否.这里只是举个例子
Stu.ID的前3位是年级ID,所以可以用下面的代码获取学生表与年级表的关联.这是一个很庆幸的例子.但是如果grade.ID是不定长的情况就无能为力了(不要管需求和实现是否合理,我只是寻求linq的语法).
我的问题是在做join的时候,linq能否写成 stu.ID.IndexOf(grade.ID) ==0类似的写法

var a = from stu in tempStuList
join grade in tempGradeList
on stu.ID.Substring(0, 3) equals grade.ID
into tempGradeTable
from tempItem in tempGradeTable
select new { StuID = stu.ID, StuName = stu.StuName, GradeName = tempItem == null ? "" : tempItem.GrideName };
...全文
195 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
threenewbee 2011-07-13
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
public class Student
{
public String ID { get; set; }
public String StuName { get; set; }
}
public class Grade
{
public String ID { get; set; }
public String GrideName { get; set; }
}

static void Main(string[] args)
{
List<Student> tempStuList = new List<Student>() {
new Student(){ ID="001001", StuName="a"},
new Student(){ ID="002001", StuName="b"},
new Student(){ ID="002001", StuName="c"},
new Student(){ ID="003001", StuName="d"},
new Student(){ ID="003001", StuName="e"},
};

List<Grade> tempGradeList = new List<Grade>() {
new Grade(){ ID="001", GrideName = "g1"},
new Grade(){ ID="002", GrideName = "g2"},
new Grade(){ ID="003", GrideName = "g3"},
};

var a = from stu in tempStuList
select new { StuID = stu.ID, StuName = stu.StuName, GradeName = (tempGradeList.Where(x => stu.ID.IndexOf(x.ID) == 0).Count() > 0 ? tempGradeList.Where(x => stu.ID.IndexOf(x.ID) == 0).First().GrideName : "") };

a.ToList().ForEach(x => Console.WriteLine(x));

}
}
}
threenewbee 2011-07-13
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
public class Student
{
public String ID { get; set; }
public String StuName { get; set; }
}
public class Grade
{
public String ID { get; set; }
public String GrideName { get; set; }
}

static void Main(string[] args)
{
List<Student> tempStuList = new List<Student>() {
new Student(){ ID="001001", StuName="a"},
new Student(){ ID="002001", StuName="b"},
new Student(){ ID="002001", StuName="c"},
new Student(){ ID="003001", StuName="d"},
new Student(){ ID="001001", StuName="e"},
};

List<Grade> tempGradeList = new List<Grade>() {
new Grade(){ ID="001", GrideName = "g1"},
new Grade(){ ID="002", GrideName = "g2"},
new Grade(){ ID="003", GrideName = "g3"},
};

var a = from stu in tempStuList
select new { StuID = stu.ID, StuName = stu.StuName, GradeName = (tempGradeList.Where(x => stu.ID.IndexOf(x.ID) == 0).SingleOrDefault().GrideName) };

a.ToList().ForEach(x => Console.WriteLine(x));

}
}
}
bearben2010 2011-07-13
  • 打赏
  • 举报
回复
Tim老兄能给写一下么?我linq不熟,一时半会写不出来.呵呵,谢谢
宝_爸 2011-07-13
  • 打赏
  • 举报
回复
这样是可以的


class GradeComparer : IEqualityComparer<string>
{
public bool Equals(string b1, string b2)
{
string stuId = b1.Length < b2.Length ? b2 : b1;
string gradeId = b1.Length < b2.Length ? b1 : b2;

return stuId.StartsWith(gradeId);
}


public int GetHashCode(string bx)
{
return 1; //返回同样的值,在Equals中进行真正的比较。可能效率会稍差。如果GetHashCode返回不同的值,Equals不会被调用。
}
}


GradeComparer gradeComparer = new GradeComparer();
var query = tempStuList.Join(tempGradeList,
s => s.ID,
g => g.ID,
(s, g) => new { ID = s.ID, Name = s.StuName, GID = g.ID, GName = g.GrideName},
gradeComparer);

foreach (var obj in query)
{
Console.WriteLine(obj.ID, obj.Name, obj.GID, obj.GName);
}
q107770540 2011-07-13
  • 打赏
  • 举报
回复
你既然使用了JOIN 就要遵守JOIN的语法 使用 equals关键字

如果你一定要使用 stu.ID.IndexOf(grade.ID) ==0 类似这样的写法

你可以使用 WHERE关键字 结合 ANY()方法来实现
宝_爸 2011-07-13
  • 打赏
  • 举报
回复
下面是我的实验,目前不行,Equals不被调用。拿出来抛砖引玉。



class GradeComparer : IEqualityComparer<string>
{
public bool Equals(string b1, string b2)
{
string stuId = b1.Length < b2.Length ? b2 : b1;
string gradeId = b1.Length < b2.Length ? b1 : b2;

return stuId.StartsWith(gradeId);
}


public int GetHashCode(string bx)
{
return bx.GetHashCode();
}
}

GradeComparer gradeComparer = new GradeComparer();
var query = tempStuList.Join(tempGradeList,
s => s.ID,
g => g.ID,
(s, g) => new { ID = s.ID, Name = s.StuName, GID = g.ID, GName = g.GrideName},
gradeComparer);

foreach (var obj in query)
{
Console.WriteLine(obj.ID, obj.Name, obj.GID, obj.GName);
}
宝_爸 2011-07-13
  • 打赏
  • 举报
回复
普通的join也不行
Enumerable.Join<TOuter, TInner, TKey, TResult> Method (IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter, TKey>, Func<TInner, TKey>, Func<TOuter, TInner, TResult>)
Func<TOuter, TKey>制定Student的key,是访问不到Inner中的对象的。


可以试一试

Enumerable.Join<TOuter, TInner, TKey, TResult> Method (IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter, TKey>, Func<TInner, TKey>, Func<TOuter, TInner, TResult>, IEqualityComparer<TKey>)

IEqualityComparer中进行比较

threenewbee 2011-07-13
  • 打赏
  • 举报
回复
使用 Join() 方法,LINQ 表达式貌似不行。
HDNGO 2011-07-13
  • 打赏
  • 举报
回复
你不是用Substring解决了?
bearben2010 2011-07-13
  • 打赏
  • 举报
回复
我想要的是on stu.ID.IndexOf(grade.ID) == 0类似这样的写法,但是这在Linq中是语法错误
HDNGO 2011-07-13
  • 打赏
  • 举报
回复
你现在写的有什么问题?

8,497

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 LINQ
社区管理员
  • LINQ
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧