У меня есть несколько таблиц User, UserSite, Site & Company. UserSite - это отношение «многие ко многим» и сайт, содержащий идентификатор компании.
У меня проблема с созданием запроса Linq для выбора Пользователей с их сайтами и сведениями о компании, и это усложняет то, что происходит много фильтрации. Вы можете фильтровать по пользователю, компании и сайту на веб-странице.
При поиске по сайту имеет смысл показывать этот сайт в результатах. Однако при поиске по пользователю я просто хочу взять первый сайт, найденный для этого пользователя, поэтому удаляю дублирующиеся строки. В T-SQL я бы сделал подчиненное объединение и взял бы верхнюю 1, нет проблем. Однако с Linq я борюсь за это. Так много, что я думаю вернуться к Store Procs.
Приведенный ниже код возвращает несколько строк для пользователя из-за присоединения к сайту, как я могу вернуть одну строку для пользователя при фильтрации по сайту.
var users = from u in _arcContext.Users
join us in _arcContext.UserSites on u.Id equals us.UserId
join s in _arcContext.Sites on us.SiteId equals s.Id
join c in _arcContext.Companies on s.CompanyId equals c.Id
where
(!userSearchParams.UserId.HasValue || u.Id == userSearchParams.UserId) &&
((String.IsNullOrEmpty(userSearchParams.UserText) || userSearchParams.UserId.HasValue) || // User Text
(u.FirstName.StartsWith(userSearchParams.UserText, StringComparison.InvariantCultureIgnoreCase)
|| u.LastName.StartsWith(userSearchParams.UserText, StringComparison.InvariantCultureIgnoreCase)
|| u.Username.StartsWith(userSearchParams.UserText, StringComparison.InvariantCultureIgnoreCase))
) &&
((!userSearchParams.CompanyId.HasValue || c.Id == userSearchParams.CompanyId)) && // Company Id
((String.IsNullOrEmpty(userSearchParams.CompanyText) || userSearchParams.CompanyId.HasValue) || // Company Text
(c.Name.StartsWith(userSearchParams.CompanyText, StringComparison.InvariantCultureIgnoreCase)
|| c.Country.StartsWith(userSearchParams.CompanyText, StringComparison.InvariantCultureIgnoreCase)
|| c.City.StartsWith(userSearchParams.CompanyText, StringComparison.InvariantCultureIgnoreCase))
) &&
((!userSearchParams.SiteId.HasValue || s.Id == userSearchParams.SiteId)) && // Site Id
((String.IsNullOrEmpty(userSearchParams.SiteText) || userSearchParams.SiteId.HasValue) || // Site Text
(s.Name.StartsWith(userSearchParams.SiteText, StringComparison.InvariantCultureIgnoreCase)
|| s.Country.StartsWith(userSearchParams.SiteText, StringComparison.InvariantCultureIgnoreCase)
|| s.City.StartsWith(userSearchParams.SiteText, StringComparison.InvariantCultureIgnoreCase))
)
select new UserToSiteAndCompany()
{
User = u,
Site = s,
Company = c
};
Обновление 1
var site = (from u in _arcContext.Users
join us in _arcContext.UserSites on u.Id equals us.UserId
join s in _arcContext.Sites on us.SiteId equals s.Id
where
((userSearchParams.SiteId.HasValue ? s.Id == userSearchParams.SiteId : true)) && // Site Id
((String.IsNullOrEmpty(userSearchParams.SiteText) || userSearchParams.SiteId.HasValue) || // Site Text
(s.Name.StartsWith(userSearchParams.SiteText, StringComparison.InvariantCultureIgnoreCase)
|| s.Country.StartsWith(userSearchParams.SiteText, StringComparison.InvariantCultureIgnoreCase)
|| s.City.StartsWith(userSearchParams.SiteText, StringComparison.InvariantCultureIgnoreCase))
)
select new { UserSite = us, Site = s}).Take(1);
var users = from u in _arcContext.Users
join us in _arcContext.UserSites on u.Id equals us.UserId
join s in site on us.SiteId equals s.Site.Id
join c in _arcContext.Companies on s.Site.CompanyId equals c.Id
where
(userSearchParams.UserId.HasValue ? u.Id == userSearchParams.UserId : true) &&
((String.IsNullOrEmpty(userSearchParams.UserText) || userSearchParams.UserId.HasValue) || // User Text
(u.FirstName.StartsWith(userSearchParams.UserText, StringComparison.InvariantCultureIgnoreCase)
|| u.LastName.StartsWith(userSearchParams.UserText, StringComparison.InvariantCultureIgnoreCase)
|| u.Username.StartsWith(userSearchParams.UserText, StringComparison.InvariantCultureIgnoreCase))
) &&
((userSearchParams.CompanyId.HasValue ? c.Id == userSearchParams.CompanyId : true)) && // Company Id
((String.IsNullOrEmpty(userSearchParams.CompanyText) || userSearchParams.CompanyId.HasValue) || // Company Text
(c.Name.StartsWith(userSearchParams.CompanyText, StringComparison.InvariantCultureIgnoreCase)
|| c.Country.StartsWith(userSearchParams.CompanyText, StringComparison.InvariantCultureIgnoreCase)
|| c.City.StartsWith(userSearchParams.CompanyText, StringComparison.InvariantCultureIgnoreCase))
)
select new UserToSiteAndCompany()
{
User = u,
Site = s.Site,
Company = c
};