Мы используем EF 4.3 для нашего уровня данных и имеем общий шаблон репозитория. Backend - это SQL 2008 R2, а проект .NET 4.0/MVC 3, но я не думаю, что эти факторы в этом вопросе.EF 4.3 Многократная ошибка перечисления
В принципе, у нас есть одно-много отношений в нашей базе данных по двум объектам. Один - для «Ловушек», а второй - для «Активность ловушки». Смысл, когда одна из этих «ловушек» развернута, все, что происходит с этой ловушкой, хранится в таблице активности трейпа. Должен быть довольно простой способ сделать это.
Отношения определяются с помощью FK в таблице «Активность трейпа» в PK таблицы «Ловушки». Обе таблицы имеют PK.
В нашем сервисном слое мне нужно запросить список «Ловушек» с датой развертывания этих ловушек. Это выполняется с помощью следующего фрагмента кода:
var traps = this.trapRepository.Find(x => x.DeploymentYear == 2012).Select(x => new TrapHomeViewModel
{
County = x.County.Name,
DeploymentDate = x.TrapActivities.First(y => y.ActivityType == 1).ActivityDate,
State = x.County.CountyState.Abbreviation,
Latitude = x.Latitude,
Longitude = x.Longitude,
TrapId = x.TrapID,
TrapNumber = x.SerialNumber,
Centroid = x.TrapCentroid
}).ToList();
Вопрос касается свойства DeploymentDate. Как написано, это займет 25 секунд, чтобы вернуть список из примерно 3000 предметов. Обновление таблицы Trap, чтобы дата развертывания будут храниться там и заполнение этой строки:
DeploymentDate = x.DeploymentDate.Value.Date
Результаты за время менее 1 сек ответа. Теперь я думаю, что я знаю, что здесь происходит (несколько перечислений из набора данных), но то, что я думал, что произойдет бы запрос похож на следующее:
SELECT Counties.Name, TrapActivities.ActivityDate, States.Abbreviation,
Traps.Latitude, Traps.Longitude, Traps.TrapID, Traps.SerialNumber, Traps.TrapCentroid
FROM TrapActivities INNER JOIN
Traps ON TrapActivities.TrapID = Traps.TrapID INNER JOIN
Counties ON Traps.CountyID = Counties.CountyID INNER JOIN
States ON Counties.State = States.FIPS_Code
WHERE (TrapActivities.ActivityType = 1)
... но это не кажется, случай. Со всей исходной информацией выше, где я заблудился при заполнении этой модели представления? Я не думаю, что раньше сталкивался с этим вопросом, но это также гораздо больший набор данных, чем некоторые из наших других проектов. Любое руководство по этому вопросу будет очень полезно. Если мне нужно предоставить любую другую информацию, пожалуйста, дайте мне знать.
РЕДАКТИРОВАТЬ
В соответствии с просьбой GenericRepository Найти способ и конструкторы:
public class GenericRepository<T> : IGenericRepository<T>
where T : class
{
private readonly IObjectSet<T> objectSet;
private ObjectContext context;
public GenericRepository()
: this(new APHISEntities())
{
}
public GenericRepository(ObjectContext context)
{
this.context = context;
this.objectSet = this.context.CreateObjectSet<T>();
}
public IEnumerable<T> Find(Func<T, bool> predicate)
{
return this.objectSet.Where(predicate);
}
EDIT 2
Это пример SQL, генерируемого кода выше:
exec sp_executesql N'SELECT
[Extent1].[TrapActivityID] AS [TrapActivityID],
[Extent1].[TrapID] AS [TrapID],
[Extent1].[ActivityType] AS [ActivityType],
[Extent1].[Notes] AS [Notes],
[Extent1].[AgentID] AS [AgentID],
[Extent1].[ActivityDate] AS [ActivityDate],
[Extent1].[CreatedOn] AS [CreatedOn],
[Extent1].[EditedOn] AS [EditedOn],
[Extent1].[Deleted] AS [Deleted],
[Extent1].[VisualInspectionID] AS [VisualInspectionID]
FROM [dbo].[TrapActivities] AS [Extent1]
WHERE [Extent1].[TrapID] = @EntityKeyValue1',N'@EntityKeyValue1 uniqueidentifier',@EntityKeyValue1='FEBC7ED4-E726-4F5E-B2BA-FFD53AB7DF34'
Мне кажется, что он принимает список идентификаторов ловушек, а затем запускает запрос для каждого из них, в результате чего генерируются тысячи выражений SQL. Похоже, что он также выполняет отдельные запросы для информации округа.
Лучшая ставка в этой ситуации и для будущих ситуаций - запустить профилировщик, такой как профилировщик Anjlab sql в вашей базе данных. Он покажет вам точный SQL, который выполняется, и как долго выполняется каждый вызов. Затем вы сможете увидеть, не делает ли это что-то супер неэффективно. Вероятно, вам просто нужно добавить некоторые индексы в свою базу данных, чтобы ускорить их. Когда вы найдете запрос, который занимает 25 секунд, SSMS имеет возможность просмотреть путь выполнения, и вы должны увидеть, где проблемы. – NibblyPig
Вы можете точно увидеть, какой запрос генерируется путем захвата сетевого трафика (Wire Shark сделает это) и посмотрев на него, а затем посмотрите, есть ли у вас индексы для его оптимизации. Вы можете быть удивлены запросом, который он создает - я был с некоторыми из моих. – itsmatt
Как выглядит метод 'Find' вашего репозитория? –