У меня есть таблица MembershipGroups, связанная с дочерней таблицей Members. В таблице «Члены» есть столбец «Состояние», для которого можно установить значение «Активно» или «Неактивно».

Я хочу выбрать все группы членства и только их активных участников

В качестве примера,

Группы участников

ID ---- Заголовок

1 ----- Группа №1

2 ----- Группа №2

< Сильный > Пользователи

MembershipGroupID-Name - Статус

1 ------------------------- Джон ---- Активный

1 ------------------------- Салли ---- Неактивно

1 ------------------------- Дэвид --- Неактивен

Я пытаюсь создать запрос, который выглядит примерно так (в настоящее время не работает):

var query = from mg in db.MembershipGroups
where mg.Members.Status = "Active"
select mg

Результат для этого примера должен вернуть MembershipGroup с ID # 1 только с одной дочерней сущностью Member.

Как можно использовать LINQ-to-SQL для выбора родительского объекта, который фильтрует дочерние объекты? Если бы я использовал прямой T-SQL, то это было бы простое соединение с предложением where, но, похоже, это было бы намного сложнее сделать с использованием LINQ-to-SQL.

2
user330366 29 Авг 2011 в 20:10

3 ответа

Лучший ответ

Изменить - обновлен ответ, чтобы вернуть объект MemberShipGroup.

var query = (from mg in db.MembershipGroups
            join m in db.Members.Where(mem => mem.Status == "Active")
            on mg.ID equals m.MembershipGroups into members
            select new
            {
               MembershipGroup = mg,
               Members = members
            }).AsEnumerable()
              .Select(m => new MembershipGroup  
                           {
                             ID = m.MembershipGroup.ID,
                             Title = m.MembershipGroup.Title,
                             Members = m.Members 
                           });
4
Aducci 29 Авг 2011 в 17:59

В LINQ to SQL вы можете использовать метод AssociateWith в DataLoadOptions, чтобы установить дочерний фильтр на уровне контекста.

DataLoadOptions opt = new DataLoadOptions();
opt.AssociateWith<Member>(m => m.Status == "Active");
db.LoadOptions = opt;

Имея это место, вы можете просто вернуть свои группы участников (или отфильтровать их по активным с помощью where mg.Any(group => group.Members.Status == "Active"). Затем, когда вы попытаетесь перейти к элементам этой группы, будут возвращены только активные из-за LoadOptions.

См. Также http://msdn.microsoft.com /en-us/library/system.data.linq.dataloadoptions.associatewith.aspx. Одно предупреждение: как только вы установите LoadOptions в экземпляре контекста, вы не сможете его изменить. Вы можете захотеть использовать индивидуальный контекст, чтобы использовать эту опцию.

В качестве альтернативы вы можете использовать модель наследования LINQ to SQL, чтобы создать тип ActiveMember, используя столбец Status в качестве дискриминатора, а затем создать связь между типами MemberGroups и ActiveMembers. Это был бы подход, который вам нужно было бы использовать для моделирования этого с помощью Entity Framework, если вы думаете о том, чтобы идти по этому маршруту, а также EF не поддерживает концепцию LoadOptions.

1
Jim Wooley 29 Авг 2011 в 20:10

Убедитесь, что вы включаете дочерние объекты, которые вы пытаетесь фильтровать, в запрос.

Например.

Var query = db.MembershipGroups .Include («Члены») .Where (m => m.Members.Status == «Активный»);

0
Winger 29 Авг 2011 в 16:17