Query: FromSql and SqlParameter issue when using with Include methods
See original GitHub issueWhen using FromSql with SqlParameters and Include methods, it is failing with an exception It seems the query is executing twice and gives error
Exception message: "The SqlParameter is already contained by another SqlParameterCollection."
Stack trace: at System.Data.SqlClient.SqlParameterCollection.Validate(Int32 index, Object value)
at System.Data.SqlClient.SqlParameterCollection.Add(Object value)
at Microsoft.EntityFrameworkCore.Storage.Internal.DynamicRelationalParameter.AddDbParameter(DbCommand command, Object value)
at Microsoft.EntityFrameworkCore.Storage.Internal.CompositeRelationalParameter.AddDbParameter(DbCommand command, Object value)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalParameterBase.AddDbParameter(DbCommand command, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.CreateCommand(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.BufferlessMoveNext(Boolean buffer)
at Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
at Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.IncludeCollection(Int32 includeId, INavigation navigation, INavigation inverseNavigation, IEntityType targetEntityType, IClrCollectionAccessor clrCollectionAccessor, IClrPropertySetter inverseClrPropertySetter, Boolean tracking, Object entity, Func`1 relatedEntitiesFactory)
at lambda_method(Closure , QueryContext , UserFilterGroup , Object[] )
at Microsoft.EntityFrameworkCore.Query.Internal.IncludeCompiler._Include[TEntity](QueryContext queryContext, TEntity entity, Object[] included, Action`3 fixup)
at lambda_method(Closure , UserFilterGroup )
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__17`2.MoveNext()
at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at RaptorWeb.DataRepository.UserFilterDataRepository.GetUserFilterGroups(UserFilterGroupSearchCriteria criteria)
at RaptorWeb.Controllers.Api.UserFilterGroupApi.GetUserFilterGroups(UserFilterGroupSearchCriteria criteria)
Code
public IEnumerable<UserFilterGroup> GetUserFilterGroups(UserFilterGroupSearchCriteria criteria)
{
List<SqlParameter> parameters = GenerateSqlParameters(criteria);
parameters.Add(new SqlParameter("@pageNumber", (criteria.PageNumber * criteria.Rows)));
parameters.Add(new SqlParameter("@rows", criteria.Rows));
var query = CurrentDbContext.UserFilterGroups.FromSql(@"SELECT * FROM (" + GenerateCriteriaQuery(criteria) + @")C
ORDER BY NAME OFFSET @pageNumber ROWS FETCH NEXT @rows ROWS ONLY"
, parameters.ToArray());
return query.Include(x => x.UserFilterValues).Include(x => x.UserFilterDefaultSettings).ToList();
}
The GenerateSqlParameters function creates the parameter list
The SQl query created is :
SELECT * FROM ( SELECT * FROM RaptorSys.UserFilterGroups WHERE FilterType = @FilterType AND SiteGuid = @SiteGuid AND UserId = @UserId) C
ORDER BY NAME OFFSET @pageNumber ROWS FETCH NEXT @rows ROWS ONLY
The method is failing at the last statement while executing the query
return query.Include(x => x.UserFilterValues).Include(x => x.UserFilterDefaultSettings).ToList();
If I remove the Include methods and just call ToList(), it is working fine
Further technical details
EF Core version: 2.0.1 Database Provider: Microsoft.EntityFrameworkCore.SqlServer Operating system: Windows 7 IDE: (e.g. Visual Studio 2017 15.5.4)
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:9 (6 by maintainers)
Top Results From Across the Web
Include with FromSqlRaw and stored procedure in EF Core ...
This does not work in my case because I am using a derived type. When using derived type from the type that is...
Read more >SQL Queries - EF Core
The FromSql and FromSqlInterpolated methods are safe against SQL injection, and always integrate parameter data as a separate SQL parameter.
Read more >Executing Raw SQL Queries using FromSql Method
The FromSql method in Entity Framework Core is used to execute raw SQL queries against the database and return the results as entities....
Read more >Raw SQL Queries in EF-Core - Learn Entity Framework Core 7
The SQL queries cannot use the join queries to get the previous data, they should use the Include method instead.
Read more >Calling Stored Procedures with the Entity Framework in . ...
This article won't solve these issues, but it will show you how to make calls to stored procedures using the version of Entity...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
In our application we start getting this bug in some cases where we using
.Includes()
andSqlParameters
that streams a list of items into a TVP-field. I found a workaround to clone theSqlParameter
if they already is attached to anotherDbCommand
, see changes in https://github.com/aspnet/EntityFrameworkCore/compare/master...Tasteful:bugfix/11370?expand=1#diff-92cbd310a2d450c3125d02f8544480a6To make a formal PR with the fix I need some direction to get it correct:
SqlServer
-project and use a separate implementation only forSqlServers
?SqlServer
-project I need to do some overrides on theRelationalParameterBuilder
, but that implementation is using a private fieldList<IRelationalParameter> _parameters
that all theAdd*
-methods are using, can I change this to a protected property instead?@ajcvickers @smitpatel
Putting this on the backlog to look at post 2.1.
@punssoma Can you try using automatically generated parameters instead of using explicit SqlParameter objects? For example: