LINQ to Entity Framwework Несколько объединений с несколькими критериями динамического поиска - PullRequest
2 голосов
/ 02 июля 2010

Суть проблемы заключается в том, что у нас есть таблица выпускников (одна запись на человека), а также пара других таблиц (от одной до многих), которые имеют информацию о степени и информации об интересах. На экране поиска в нашем приложении вы можете искать критерии, охватывающие все три таблицы (на самом деле полей и таблиц на самом деле больше, чем показано в примере ниже, но я стараюсь сделать его простым).

Приведенный ниже код работает (например, правильно возвращает людей без степеней), но все еще чувствует себя немного неуклюжим или чрезмерно сложным для меня. Есть ли более простые способы сделать это? ПРИМЕЧАНИЕ. Я прошел через несколько итераций / подходов, чтобы вернуть правильные данные.

 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 голосов
/ 12 сентября 2012
 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();
}
0 голосов
/ 02 июля 2010

Возможно, вы захотите посмотреть библиотеку DynamicQuery здесь: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Возможно, вы сможете объяснить, как вы заполняете критерии AlumniSearchCriteria (UI -> AlumniSearchCriteria).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...