Во-первых, поскольку мы обеспокоены производительностью, убедитесь, что ваша база данных имеет индексы для всех этих столбцов UserId и RoleId.
Поскольку у вас есть несколько UserRoles, в том числе в соединении, это расточительно увеличивает мощность вашего запроса, а затем вызывает вызов FirstOrDefault и возвращает его обратно. один? вы не показали, как вы выбираете конкретного пользователя, но я оставлю это до вас, чтобы исправить, если только он не фильтруется в одном из ваших источников данных.
Кроме того, свойство role на вашем анонимном объекте: каждый раз, когда вы его касаетесь, вы попадаете в базу данных. Это очень хорошо может быть источником проблем с производительностью. Если это приемлемо для кэширования этой информации, завершение подзапроса вызовом ToList() было бы разумным.
Этот подзапрос может стать еще одним источником неприятностей, особенно если вы используете ToList - это будет еще одна поездка в базу данных, поэтому убедитесь, что мощность основного запроса не установлена, чтобы контролировать количество поездок.
var user = (from uc in Db.UserCredentials
join up in Db.UserProfiles on uc.UserId equals up.UserId
//where uc.UserId == somePassedInUserId /* add this line if your datasources aren't filtered */
select new {
Credetial = uc,
Profile = up,
Roles = (from ur in Db.UserRoles join r in Db.Roles on ur.RoleId equals r.RoleId
where ur.UserId == uc.UserId select r).ToList()
.FirstOrDefault();
EF автоматически создает свойства навигации для связи, поэтому вам не нужно использовать соединения. –
Вы указываете EF и LINQ to SQL. Что вы используете? SQL, сгенерированный каждым, может быть совсем другим. Отправьте сгенерированный SQL и укажите, где вы считаете, что он неэффективен. Независимо от того, подумайте об этом как о графе объектов, а не о наборах с объединениями, и вы можете найти лучший вариант. –