我有以下查询期望根据所选学校仅从实体中检索唯一值:
var semesters = (from cou in db.Courses
join sem in db.Semesters on cou.SemesterID equals sem.ID
where cou.FacultyID == id
select new SemestersModel {
SemesterID = sem.ID,
SemesterText = sem.Semester })
.Distinct()
.ToList();
但是它会返回实体课程中包含的所有学期
请帮助我只抓住不同的学期名称,例如
P.S。我的问题与此问题不同Distinct in Linq based on only one field of the table
答案 0 :(得分:3)
您在创建Distinct
后使用SemestersModel
,如果该类型未覆盖Equals
+ GetHashCode
,则只会比较引用,在这种情况下是不同的。
因此,要么覆盖这些方法,请为IEqualityComparer<SemestersModel>
提供自定义Linq-To-Entities
(Linq-To-Sql
或Distinct
不支持),或者只使用Distinct
匿名类型:
var semesters = from cou in db.Courses
join sem in db.Semesters
on cou.SemesterID equals sem.ID
where cou.FacultyID == id
select new { SemesterID = sem.ID, SemesterText = sem.Semester };
List<SemestersModel> uniqueSemesterList = semesters
.Distinct()
.Select(x => new SemestersModel {
SemesterID = x.SemesterID,
SemesterText = x.SemesterText })
.ToList(); // due to deferred execution only now the query above will be executed together with Distinct
此查询可以转换为有效的SQL(省略join
和where
):
SELECT DISTINCT SemesterID, SemesterText FROM dbo.Semesters
将执行查询,并在内存中创建唯一的SemestersModel
实例以填充列表。
答案 1 :(得分:2)
如果您按照要分隔的字段对学期进行分组,则选择该组的第一个,现在您可以将结果投影到SemestersModel实例中。
(from cou in db.Courses
join sem in db.Semesters on cou.SemesterID equals sem.ID
where cou.FacultyID == id
select sem)
.GroupBy(sem => sem.Semester)
.Select(g => g.FirstOrDefault())
.Select(sem => new SemestersModel {
SemesterID = sem.ID,
SemesterText = sem.Semester
})
.ToList();
答案 2 :(得分:1)
不同的方法使用IEqualityComparer
来比较对象。因此,如果您使用Distinct()
过滤记录,则可以创建一个实施IEqualityComparer
的比较器并将其传递给Distinct()
这是一个例子。
class Employee
{
public int Id { get; set; }
public String Name { get; set; }
}
class EmpEqualityComparer : IEqualityComparer<Employee>
{
public bool Equals(Employee x, Employee y)
{
if (x.Id == y.Id && x.Name == y.Name)
return true;
else
return false;
}
public int GetHashCode(Employee obj)
{
int hCode = obj.Id;
return hCode.GetHashCode();
}
}
现在你可以测试一下。
List<Employee> emp = new List<Employee>();
emp.Add(new Employee() { Id = 123, Name = "Saket"});
emp.Add(new Employee() { Id = 123, Name = "Saket" });
emp.Add(new Employee() { Id = 123, Name = "Saket" });
emp.Add(new Employee() { Id = 123, Name = "Saket" });
emp.Add(new Employee() { Id = 123, Name = "Saket" });
emp.Add(new Employee() { Id = 123, Name = "Saket" });
emp.Add(new Employee() { Id = 123, Name = "Saket" });
EmpEqualityComparer eqi = new EmpEqualityComparer();
var employees = (from e in emp
select new Employee { Id = e.Id, Name = e.Name }).Distinct(eqi).ToList();
希望它有所帮助。
答案 3 :(得分:0)
这是不可能的......
您需要让SemesterModel类继承IEquatable。并覆盖两个函数Equals和GetHashCode。
public class SemestersModel : IEquatable<SemestersModel >{
public string SemesterID { get; set; }
public string SemesterText { get; set; }
public bool Equals(SemestersModel comp)
{
if (SemesterID == comp.SemesterID && SemesterText == comp.SemesterText)
return true;
return false;
}
public override int GetHashCode()
{
int hSemesterID = SemesterID == null ? 0 : SemesterID.GetHashCode();
int hSemesterText = SemesterText == null ? 0 : SemesterText.GetHashCode();
return hSemesterID ^ hSemesterText;
}}