построитель предикатов с двумя таблицами

введите здесь описание изображения

Сторона может иметь один или несколько объектов Contact.

Я хочу выбрать все Party, название улицы которых содержит определенное ключевое слово.
Если я просто хочу выполнить поиск в Party, я могу использовать приведенный ниже код. Но как расширить его для поиска в Контактах?

public IQueryable<Party> SearchParties(List<string> keywords)
    {
        var predicate = PredicateBuilder.False<Party>();

        foreach (string word in keywords)
        {
            var keyword = word;
            predicate = predicate.Or(p => p.surname.Contains(keyword));
            predicate = predicate.Or(p => p.lastname.Contains(keyword));
            predicate = predicate.Or(p => p.number.Contains(keyword));
        }
        return db.Parties.Where(predicate);
    }  

Есть ли что-то еще, что вам нужно знать?

EDIT
Думаю, я мог бы создать еще один предикат, а затем присоединиться к ним. Что-то типа:

var predicate2 = PredicateBuilder.False<Contact>();  

... и в foreach:

predicate2 = predicate2.Or(p => p.streetname.Contains(keyword));  

Но как мне соединить predicate и predicate2 перед возвратом?

EDIT2
Или присоединиться к Party и Contact, прежде чем выполнять конструктор предикатов?

EDIT3
Вот части сгенерированных классов:

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Contact")]
public partial class Contact : INotifyPropertyChanging, INotifyPropertyChanged
{
    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

    private int _id;  
    // ...more properties  
    private EntityRef<Party> _Party;

    public Contact()
    {
    this._Party = default(EntityRef<Party>);
    OnCreated();
    }
}

person Niklas    schedule 13.06.2011    source источник


Ответы (2)


Дело в том, что у вас есть несколько контактов для одной Стороны, поэтому вы должны решить, хотите ли вы иметь Сторону, если «какой-либо из контактов соответствует названию улицы» или «все контакты соответствуют названию улицы».

Для первого случая это будет:

predicate = predicate.Or(p => p.Contacts.Any(c => c.streetname.Contains(keyword))));
person Tz_    schedule 28.06.2011
comment
Спасибо! Вы просто ждали, пока я объявлю награду за него, не так ли =) - person Niklas; 28.06.2011
comment
Я не видел вашего вопроса раньше. Я думаю, награда подняла его на вершину стека. ;) - person Tz_; 28.06.2011
comment
‹resurrect› что, если между таблицами нет явной связи? то есть без внешнего ключа? - person drzaus; 15.10.2013

Это будет работать, если ваша модель имеет контакт в качестве связанного объекта с объектом партии (и если он не имеет отношения «один ко многим»)

predicate = predicate.Or(p => p.Contact.streetname.Contains(keyword));
person Richard Forrest    schedule 13.06.2011
comment
Пробовал это, но я думаю, что нет =/. Как добавить его в качестве связанного объекта? - person Niklas; 13.06.2011
comment
Какой ORM вы используете, например. Линк к sql, EF - person Richard Forrest; 13.06.2011
comment
Linq to SQL, я начал с NerdDinner. - person Niklas; 13.06.2011
comment
Когда вы создаете свой datacontext для linq to sql из базы данных, если у таблицы party и contact есть связь внешнего ключа, она должна связать ее для вас. Вы можете попробовать обновить контекст из базы данных. - person Richard Forrest; 13.06.2011
comment
Не работает. У меня есть public EntitySet<Contact> Contacts, который, я думаю, соответствует Party с внешним ключом. Поэтому я решил поискать этот набор вместо этого: predicate = predicate.Or(p => p.Contacts.Where(c => c.streetname.Contains(keyword)))); Но он говорит, что не может неявно преобразовать в bool. - person Niklas; 13.06.2011
comment
Не могли бы вы опубликовать классы контактов и вечеринок - person Richard Forrest; 13.06.2011
comment
Вся сгенерированная модель состоит из 2,2 тыс. строк. Я думаю, что классы слишком велики, чтобы публиковать их. Но если у меня есть контакты EntitySet вместо одного контакта объекта. Разве нельзя было указать название улицы в любом случае? - person Niklas; 13.06.2011
comment
почему бы вам не передать лямбда-выражение вместо list‹string›? - person Stacker; 16.06.2011
comment
@Stacker - Что вы имеете в виду и поможет ли это моему вопросу? - person Niklas; 28.06.2011