Существует множество вопросов об использовании функций Include() и Load() для связанной информации таблицы при использовании Linq для объектов. У меня другое отношение к этому вопросу.Объекты, связанные с инфраструктурой Entity Framework, с использованием генерических файлов
Моя ситуация:
У меня есть таблица, которая содержит много времени записи для каждого пользователя в системе, и я использую хранилище шаблон и дженерики для развития, поэтому все мои сущностей имеют интерфейс, который они используют для стандартные вызовы методов. У меня отключена ленивая загрузка, и я загружаю все данные самостоятельно. Таким образом, код в хранилище для загрузки всех записей из таблицы с соответствующими таблицами, как это:
public class Repository<T> : IRepository<T> where T : class
{
protected readonly ApplicationDbContext Context;
public Repository(IConnectionHelper connection)
{
Context = connection.Context;
}
public virtual DbSet<T> ObjectSet
{
get { return Context.Set<T>(); }
}
public List<T> GetAll(String[] include, Expression<Func<T, bool>> predicate)
{
DbQuery<T> outQuery = null;
foreach (String s in include)
{
outQuery = ObjectSet.Include(s);
outQuery.Load();
}
return outQuery.Where(predicate).ToList();
}
}
Вызов метода выглядит так:
string[] includes = { "User.UserProfile", "CampaignTimeClocks.CampaignRole.Campaign", "Site", "Type" };
DateTime uTcCurrent = GetUtc();
DateTime MinClockinDate = uTcCurrent.AddHours(-10);
List<TimeClock> tcPending = _timeClock.GetAll(includes, x => (x.PendingReview || x.ClockInDate < MinClockinDate && x.ClockOutDate == null) && (x.Site.Id == currentUser.SiteId));
Когда этот метод работает и загружает первая таблица User.Profile, она загружает все записи тайм-слова и связывает их со всеми пользователями, это занимает больше минуты, это слишком долго, так как количество конечных записей составляет всего 185 записей, но начальная загрузка в запросе работает 27 000 * 560 пользователей или 15 миллионов записей, и это со временем будет намного хуже.
Вопрос в том, как это сделать без этой накладной нагрузки, я знаю, что я могу использовать цепочку, но поскольку количество включений будет меняться в зависимости от того, что есть и что я делаю с указанными данными, я не могу просто жесткий код цепи включает.
Я также попытался:
List<TimeClock> testLst = _timeClock.GetAll(x => x.PendingReview ||
(x.ClockInDate < MinClockinDate && x.ClockOutDate == null))
.Select(x => new TimeClock{Id = x.Id,
ClockInDate = x.ClockInDate,
ClockOutDate = x.ClockOutDate,
TotalClockTime = x.TotalClockTime,
Notes = x.Notes,
PendingReview = x.PendingReview,
Type = x.Type,
User = x.User,
CampaignTimeClocks = x.CampaignTimeClocks,
TimeClockAdjustments = x.TimeClockAdjustments,
Site = x.User.Site}).ToList();
Это даст мне информацию User.Profile, но места и типа свойства равны нулю.
Так что я немного потерял, как загрузить данные, которые мне нужны здесь.
Вся помощь очень ценится.
Что произойдет, если вы запустите 'Where' перед' Load'? – Shoe
Не имеет значения, где предложение where - это потому, что он загружает данные в запрос query.load(). –
Да, добавьте предикат к запросу, затем загрузите. 'ObjectSet.Where(). Include(). Load();' – Shoe