Я переношу некоторые устаревшие коды/запросы Linq-to-SQL в .NET 7/EF Core. Некоторый код, который ранее работал в L2S, теперь выдает исключение:
Уже существует открытое устройство чтения данных, связанное с этим соединением, которое необходимо сначала закрыть.
Я покопался и увидел предложения по включению MARS (но сначала при серьезном рассмотрении), а также попробовал несколько операторов .Include, которые не помогли. Это помогло.
У меня есть прямая связь таблицы Profile (родительский) -> HistoryData (дочерний). Где HistoryData.hispKey — это внешний ключ для Profile.pKey.
CREATE TABLE [dbo].[Group]
(
[gKey] [int] IDENTITY(1,1) NOT NULL,
[gName] [nvarchar](255) NOT NULL,
....
)
CREATE TABLE [dbo].[Profile]
(
[pKey] [int] IDENTITY(1,1) NOT NULL,
[pgKey] [int] NOT NULL,
[pAuthID] [nvarchar](255) NOT NULL,
[pDateUpdated] [datetime2](7) NOT NULL,
[pDateCreated] [datetime2](7) NOT NULL,
[pUpdatedBy] [varchar](255) NOT NULL,
[pCreatedBy] [varchar](255) NOT NULL
[pProfile] [ntext] NOT NULL,
[pProfileXml] [xml] NOT NULL
)
CREATE TABLE [dbo].[HistoryData]
(
[hisKey] [int] IDENTITY(1,1) NOT NULL,
[hisgKey] [int] NOT NULL,
[hispKey] [int] NOT NULL,
[hisType] [varchar](50) NOT NULL,
[hisIndex] [varchar](255) NOT NULL,
[hisDateUpdated] [datetime2](7) NOT NULL,
[hisDateCreated] [datetime2](7) NOT NULL,
[hisUpdatedBy] [varchar](255) NOT NULL,
[hisCreatedBy] [varchar](255) NOT NULL,
[hisData] [ntext] NOT NULL,
[hisDataXml] [xml] NOT NULL
)
Тогда у меня есть следующие операторы проекции, которые идентичны тем, что у меня были в Linq-to-SQL (за исключением, очевидно, использования DbContext и DataContext) ):
var profiles = dataContexts.xDS.Profiles
.Where(p => p.GroupKey == gKey)
.Where(p => options.AuthIdsToExport.Length == 0 || options.AuthIdsToExport.Contains(p.AuthID))
.OrderBy(p => p.AuthID)
.Select(p => new XmlProfileRow {
AuthId = p.AuthID,
Data = p.Data,
DataXml = p.ProfileXml,
DateCreated = p.DateCreated,
DateUpdated = p.DateUpdated
});
var historyDatas = dataContexts.xDS.HistoryDatas
// .Include( h => h.Profile ) // This did not help
.Where(h => h.GroupKey == gKey )
.Where(h => options.AuthIdsToExport.Length == 0 || options.AuthIdsToExport.Contains(h.Profile!.AuthID))
.OrderBy(h => h.Profile!.AuthID)
.ThenBy(h => h.Type)
.ThenBy(h => h.Index)
.Select(h => new XmlHistoryRow {
AuthId = h.Profile!.AuthID,
DateCreated = h.DateCreated,
DateUpdated = h.DateUpdated,
Type = h.Type,
Index = h.Index,
Data = h.Data,
DataXml = h.DataXml
});
Использование этих двух запросов изначально было написано с помощью объектов IEnumerator, и я не уверен, поможет ли «Разделенный запрос» EF Core или что-то вроде «множественного запроса» Dappers. поддержка операторов, но я определенно не могу загрузить все данные в память, мне нужно выполнить потоковую передачу результатов «Профилей» и для каждой строки потоковую передачу результатов «Исторических данных» для текущего « связанных строк.
Намерение состояло в том, чтобы не создавать новые запросы для строк HistoryData каждого профиля.
Упрощенный код, демонстрирующий проблема в следующем:
var profileEnumerator = profiles.GetEnumerator();
var historyEnumerator = historyDatas.GetEnumerator();
var currentHistory = historyEnumerator.MoveNext();
var currentProfile= profileEnumerator.MoveNext();
Последний вызов выдает исключение со стеком вызовов:
at Microsoft.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)
at Microsoft.Data.SqlClient.SqlCommand.ValidateCommand(Boolean isAsync, String method)
at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource'1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String method)
at Microsoft.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable'1.Enumerator.InitializeReader(Enumerator enumerator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable'1.Enumerator.c.b__21_0(DbContext _, Enumerator enumerator)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func'3 operation, Func'3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable'1.Enumerator.MoveNext()
at UserQuery.ExportDataAsync(String groupName, DataOptions options, DataContexts dataContexts), line 154
Каково подходящее решение при работе в EF Core?
К вашему сведению, сгенерированный SQL, отображаемый до точки исключения, выглядит следующим образом ( что кажется правильным):
info: 10/21/2024 10:30:59.384 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
Executed DbCommand (1ms) [Parameters=[@__gKey_0='1009' (Nullable = true)], CommandType='Text', CommandTimeout='30']
SELECT [p].[pAuthID] AS [AuthId], [h].[hisDateCreated] AS [DateCreated], [h].[hisDateUpdated] AS [DateUpdated], [h].[hisType] AS [Type], [h].[hisIndex] AS [Index], [h].[hisData] AS [Data], [h].[hisDataXml] AS [DataXml]
FROM [HistoryData] AS [h]
LEFT JOIN [Profile] AS [p] ON [h].[hispKey] = [p].[pKey]
WHERE [h].[hisgKey] = @__gKey_0
ORDER BY [p].[pAuthID], [h].[hisType], [h].[hisIndex]
fail: 10/21/2024 10:30:59.385 RelationalEventId.CommandError[20102] (Microsoft.EntityFrameworkCore.Database.Command)
Failed executing DbCommand (0ms) [Parameters=[@__gKey_0='1009' (Nullable = true)], CommandType='Text', CommandTimeout='30']
SELECT [p].[pAuthID] AS [AuthId], [p].[pProfile] AS [Data], [p].[pProfileXml] AS [DataXml], [p].[pDateCreated] AS [DateCreated], [p].[pDateUpdated] AS [DateUpdated]
FROM [Profile] AS [p]
WHERE [p].[pgKey] = @__gKey_0
ORDER BY [p].[pAuthID]
Подробнее здесь: https://stackoverflow.com/questions/791 ... ociated-wi
Linq-to-SQL переносится на EF Core, с этой командой уже связан открытый DataReader. ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Linq to SQL переносится на EF Core. С этой командой уже связан открытый DataReader.
Anonymous » » в форуме C# - 0 Ответы
- 21 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Linq to SQL переносится на EF Core. С этой командой уже связан открытый DataReader.
Anonymous » » в форуме C# - 0 Ответы
- 15 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Linq-to-SQL переносится на EF Core, с этой командой уже связан открытый DataReader.
Anonymous » » в форуме C# - 0 Ответы
- 15 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Linq-to-SQL переносится на EF Core, с этой командой уже связан открытый DataReader.
Anonymous » » в форуме C# - 0 Ответы
- 10 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Linq-to-SQL переносится на EF Core, с этой командой уже связан открытый DataReader.
Anonymous » » в форуме C# - 0 Ответы
- 13 Просмотры
-
Последнее сообщение Anonymous
-