question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Is there a way to prevent a value from being converted into a SqlParameter?

See original GitHub issue

I’m trying to work around an issue in SqlCe 3.0, where you cannot use a SQL parameter with a db function, such as COALESCE, or ISNULL.

Is there a way of telling LinqToDb to not parameterize a specific value?

I’ve been digging into the source, but was wondering if there was a built in way of doing this, before I look at making a fork.

Steps to reproduce

Use a query that includes a coalesce on a SQL CE database.

var query = from c in context.MyTable
            where (c.StartDate ?? SqlDateTime.MinValue.Value) <= DateTime.Now
            select c;

This produces the following SQL

-- MyContext SqlCe
DECLARE @p1 DateTime
SET     @p1 = '1753-01-01'
DECLARE @p2 DateTime
SET     @p2 = '2018-10-17 10:07:02.353'

SELECT
	[t1].[Id],
	[t1].[FirstName],
	[t1].[LastName],
	[t1].[StartDate]
FROM
	[MyTable] [t1]
WHERE
	Coalesce([t1].[StartDate], @p1) <= @p2

Here’s the exception that running the query produces.

Exception message: System.Data.SqlServerCe.SqlCeException: 'The specified argument value for the function is not valid. [ Argument # = 2,Name of function(if known) = coalesce ]'
Stack trace:
   at System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan()
   at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options)
   at System.Data.SqlServerCe.SqlCeCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at LinqToDB.Data.DataConnection.ExecuteReader(CommandBehavior commandBehavior)
   at LinqToDB.Data.DataConnection.ExecuteReader()
   at LinqToDB.Data.DataConnection.QueryRunner.ExecuteReader()
   at LinqToDB.Linq.QueryRunner.<ExecuteQuery>d__9`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

If I manually modify the SQL to the following, it executes successfully. This is what I’d like to achieve with LinqToSql if possible.

-- MyContext SqlCe
DECLARE @p1 DateTime
SET     @p1 = '2018-10-17 10:07:02.353'

SELECT
	[t1].[Id],
	[t1].[FirstName],
	[t1].[LastName],
	[t1].[StartDate]
FROM
	[MyTable] [t1]
WHERE
	Coalesce([t1].[StartDate], '1753-01-01') <= @p1

Environment details

linq2db version: MASTER, commit 9bcf33e23d9be452c39bfc47203e3b165450aad7 Database Server: SQL CE 3.0 Database Provider: SQL CE 3.0 Operating system: Windows 10 Framework version: NET Framework 4.5.1

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
sdanylivcommented, Oct 18, 2018

@matthewjones555, thanks for the PR. Looks good. But i need to check how it works with cache (try to call the same expression several times with different parameters) and write some tests (it is manadatory). Making PR should be like a game and i suppose digging into linq2db sources should give more understanding what library can do.

1reaction
sdanylivcommented, Oct 17, 2018

@matthewjones555, i’m out of computer to check this in detail, but it is possible.

  1. You can inline parameters in whole query: context.InlineParameters = true;
  2. You can write new function in some class and use in queries:
[Sql.Function(InlineParameters = true)]
public static void T Coalesce<T>(T? value, T defaultValue) where T: struct;
{
   throw new NotImplementedException();
}
  1. Wait for fix in new version, or create PR. Looking at realization, and see that this can be done easily in SqlCeSqlOptimizer
Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Best method of assigning NULL value to SqlParameter
Yes, for the value of the parameter, just use DBNull. ... method will automatically converts it to DBNull and reassign to the sqlparameter....
Read more >
Using parameterized queries to avoid SQL injection
One of the most common practices to protect the code against SQL Injection is encapsulating and parameterizing our SQL Commands. Parameterized ...
Read more >
SqlParameter Class (System.Data.SqlClient)
Initializes a new instance of the SqlParameter class that uses the parameter name and a value of the new SqlParameter. SqlParameter(String, SqlDbType).
Read more >
Dapper Parameter, SQL Injection, Anonymous and ...
The Dapper string parameter feature is a great way to protect against SQL injection. It allows developers to pass parameters directly into their...
Read more >
What is Parameter Sniffing in SQL Server?
When the procedure is compiled or recompiled, the value passed into the parameter is evaluated and used to create an execution plan.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found