具有多个动态搜索条件的LINQ to Entity Framework多个联接

时间:2010-07-02 17:20:27

标签: c# asp.net linq linq-to-entities

问题的关键在于我们有一个校友表(每人一个记录)以及其他几个具有学位信息和兴趣信息的表(一对多)。在我们的应用程序的搜索屏幕中,您可以搜索跨越所有三个表的条件(实际上有更多的字段和表格,而不是在下面的示例中显示,但我试图保持简单)。

以下代码有效(例如,适当地返回没有学位的人),但仍然感觉有点笨重或过度设计给我。有更简单的方法吗?注意:我已经经历了相当多的迭代/方法来返回正确的数据。

 public IQueryable<AlumniSearchResult> FindAlumniRecords(AlumniSearchCriteria searchCriteria)
    {
        // tables
        var alumniRecords = iuaaOlcEntities.AlumniRecords.AsQueryable();
        var degreeRecords = iuaaOlcEntities.AlumniDegrees.AsQueryable();
        var interestRecords = iuaaOlcEntities.AlumniInterests.AsQueryable();

        // typed predicates
        var alumniRecordPredicates = PredicateBuilder.True<AlumniRecord>(); // True for AND, False for OR???
        var degreePredicates = PredicateBuilder.True<AlumniDegree>();
        var interestPredicates = PredicateBuilder.True<AlumniInterest>();

        if (!String.IsNullOrEmpty(searchCriteria.lastname))
            alumniRecordPredicates = alumniRecordPredicates.And(item => item.lastname.StartsWith(searchCriteria.lastname));
        if (!String.IsNullOrEmpty(searchCriteria.firstname))
            alumniRecordPredicates = alumniRecordPredicates.And(item => item.firstname.StartsWith(searchCriteria.firstname));
        if (!String.IsNullOrEmpty(searchCriteria.nickname))
            alumniRecordPredicates = alumniRecordPredicates.And(item => item.nickname.StartsWith(searchCriteria.nickname));
        if (!String.IsNullOrEmpty(searchCriteria.maiden_lastname))
            alumniRecordPredicates = alumniRecordPredicates.And(item => item.maiden_lastname.StartsWith(searchCriteria.maiden_lastname));
        if (!String.IsNullOrEmpty(searchCriteria.city))
            alumniRecordPredicates = alumniRecordPredicates.And(item => item.city.StartsWith(searchCriteria.city));


        // degrees
        if (searchCriteria.school_name != null)
            degreePredicates = degreePredicates.And(item => item.school_name.Contains(searchCriteria.school_name));
        if (searchCriteria.degree_name != null)
            degreePredicates = degreePredicates.And(item => item.name.Contains(searchCriteria.degree_name));
        if (searchCriteria.major != null)
            degreePredicates = degreePredicates.And(item => (item.major1_name.Contains(searchCriteria.major) || item.major2_name.Contains(searchCriteria.major) || item.major3_name.Contains(searchCriteria.major)));

        // interests
        if (searchCriteria.interests != null)
            interestRecords = interestRecords.Where(item => item.interest_desc.Contains(searchCriteria.interests));

        // the queries aren't running yet but applying the predicates outside of the join
        alumniRecords = from a in iuaaOlcEntities.AlumniRecords.Where(alumniRecordPredicates).AsExpandable()
                        select a;
        degreeRecords = from b in iuaaOlcEntities.AlumniDegrees.Where(degreePredicates).AsExpandable()
                        select b;
        interestRecords = from c in iuaaOlcEntities.AlumniInterests.Where(interestPredicates).AsExpandable()
                        select c;

        return (from a in alumniRecords
                join b in degreeRecords on a.person_id equals b.person_id into temp1
                from t1 in temp1.DefaultIfEmpty()
                join c in interestRecords on t1.person_id equals c.person_id into temp2
                from t2 in temp2.DefaultIfEmpty()
                select new AlumniSearchResult
                {
                    person_id = a.person_id,
                    fullname = a.lastname + ", " + (a.firstname ?? "") + " " + (a.mid_name ?? ""),
                    emp_city = a.emp_city,
                    emp_state = a.emp_state,
                    emp_name = a.emp_name,
                    emp_title = a.emp_title
                }).Distinct();
    }

2 个答案:

答案 0 :(得分:0)

您可能希望在此处查看DynamicQuery库:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

也许您可以解释如何填写AlumniSearchCriteria(UI - &gt; AlumniSearchCriteria)。

答案 1 :(得分:0)

 var SearchData(string sc1, string sc2, string sc3, string sc4)
    {

var res = (from t1 in T1
join t2 in T2 on t1.AnyField equals t2.CorrespondentField
join t3 in T3 on t1.AnyField equals t3.CorrespondentField

where (t1.AnyField.Equals(sc1) || String.IsEmptyOrNull(sc1))
&& (t2.AnyField.Equals(sc2) || String.IsEmptyOrNull(sc2))
&& ( 
 (t3.AnyField.Equals(sc3) || String.IsEmptyOrNull(sc3)
&& 
(t3.AnyField.Equals(sc4) || String.IsEmptyOrNull(sc4)
)
);
return res.ToList();
}