UseDatabaseNullSemantics not working - sql-server

this is the query I am trying to execute:
int? i = default(int);
var orders= db.orders.Include(p => p.regions).Include(p => p.types);
int? i = default(int);
var list = orders
.Where(item => item.visible== true && ( (item.children== true) || ((item.dad== i) && item.children== false) )).OrderByDescending(item => item.year);
db is a IdentityDbContext; in its constructor I set
this.Configuration.UseDatabaseNullSemantics = true;
The generated query is the following:
SELECT
[Project1].[id] AS [id],
[Project1].[visible] AS [visible],
[Project1].[dad] AS [dad],
[Project1].[children] AS [children],
FROM ( SELECT
[Extent1].[id] AS [id],
[Extent1].[visible] AS [visible],
[Extent1].[dad] AS [dad],
[Extent1].[children] AS [children],
[Extent1].[n_unita] AS [n_unita]
FROM [dbo].[orders] AS [Extent1]
WHERE (1 = [Extent1].[visible]) AND ((1 = [Extent1].[children]) OR (([Extent1].[dad] = #p__linq__0) AND (0 = [Extent1].[children])))
) AS [Project1]
ORDER BY [Project1].[year] DESC
The problem is that with item.dad want to check also if dad is NULL, but this is not happening and I cannot understand why, where am I mistaken?
Nothing changes with this.Configuration.UseDatabaseNullSemantics = false;

This answer gave me the solution: link to answer.
There is nothing wrong with this code, a change had to be made in the class extending IdentityDbContext in order to make ef generate the correct IS NULL check.
Dad field is a foreign key and I made the mistake to tell the code that is a required field, while it is not, so I corrected the code in the following way:
modelBuilder.Entity<orders>()
.HasMany(e => e.order)
.WithOptional(e => e.dad_orders)
.HasForeignKey(e => e.dad)
.WillCascadeOnDelete(false);

Related

Why does LINQ generated SQL include multiple "IS NULL" conditions for the same column

The following query against a SQL Server 2012 database, using Entity Framework Core 3.1:
var tows = await _context.DataEntryTow
.Where(t => _context.DataEntrySample
.Any(s => s.TowId==t.TowId && (s.MicroscopeId != "0" || s.MicroscopeId == null)))
.Select (t => new { text = t.TowId, value = t.TowId });
generates this SQL:
SELECT d.tow_id AS text
FROM data_entry_tow AS d
WHERE EXISTS (
SELECT 1
FROM data_entry_sample AS d0
WHERE (d0.tow_id = d.tow_id) AND (((d0.microscope_id <> '0') OR (d0.microscope_id IS NULL)) OR (d0.microscope_id IS NULL)))
I don't think I've done anything wrong, and I'm fairly sure the query optimizer will eliminate the second (d0.microscope_id IS NULL), but it still seems like an error in the LINQ code.
MicroscopeId is defined:
public string MicroscopeId { get; set; }
Field MicroscopeId declared as nullable. So, to mimic LINQ to Objects behaviour when null != "0" is true but in SQL null <> '0' is false, EF Core generates additional OR condition.
To disable this geneeration you have to specify that when building DbContextOptions:
optionsBuilder.UseSqlServer(constr, b => b.UseRelationalNulls(true) );
Additional info: https://learn.microsoft.com/en-us/ef/core/querying/null-comparisons#using-relational-null-semantics

EF Core 3.1 produces incorrect query translation

I have the following EF Core 3.1 statement:
var orders = await _dbContext.Orders.Include(o => o.OrderReceivers)
.Where(o => o.BooleanFlag1 && o.OrderState == OrderState.SomeState && o.OrderReceivers.Any(o => o.BooleanFlag2))
.ToListAsync(cancellationToken);
and this is the generated SQL Server query:
SELECT /*All column names here*/
FROM [Schema].[Orders] AS [o]
LEFT JOIN [Schema].[OrderReceivers] AS [o0] ON [o].[Id] = [o0].[OrderId]
WHERE (([o].[ShouldSendBlackList] = CAST(1 AS bit)) AND ([o].[OrderState] = 2)) AND EXISTS (
SELECT 1
FROM [Schema].[OrderReceivers] AS [o1]
WHERE ([o].[Id] = [o1].[OrderId]) AND ([o1].[BooleanFlag2] = '1'))
ORDER BY [o].[Id], [o0].[Id]
The problem with the generated SQL Query is this part:
([o1].[BooleanFlag2] = '1')
Because this causes the second where clause to be always false!
Any ideas on what is wrong here? Thanks in advance.

UpdateAll is not working with bigint() fields

I'm quite new to CakePHP and have an issue. I'm trying to update one field in a row with this:
$options = array('conditions' => array('User.id' => $_POST['userid']));
$user = $this->User->find('first', $options);
$currentpoint = $user['User']['point'];
$correctanswerpoint = Configure::read('CORRECT_SYSTEMANSWER_POINT');
$newpoint = $currentpoint + $correctanswerpoint;
$this->User->updateAll(array('User.point'=>$newpoint), array('User.id'=>$_POST['userid']));
There are no errors, but the field point (bigint(20)) is not being updated. I've changed the field to update to another one in the same row which is of smallint type and the update goes through fine.
My debugging log seems to show that the SQL query is ok too:
[query] => UPDATE `askyoode_askyoo`.`users` AS `User` LEFT JOIN `askyoode_askyoo`.`countries` AS `Country` ON (`User`.`country_id` = `Country`.`id`) LEFT JOIN `askyoode_askyoo`.`accesstypes` AS `Accesstype` ON (`User`.`accesstype_id` = `Accesstype`.`id`) SET `User`.`point` = 57 WHERE `User`.`id` = 124
[params] => Array
(
)
[affected] => 1
[numRows] => 1
[took] => 12
)
And manually running the same SQL statement in MySQL works. Been tearing out my hair for the whole day trying to resolve this. Any help is greatly appreciated. Thanks!!

Select specific columns with repository in Entity Framework Core

I have a big table with a binary column for picture. I need to show contents of this table in a view and make it searchable. I have tried only selecting a subset of columns that are needed in this. However, the generated SQL always has all the columns of the table in the generated query.
public IQueryable<ApplicantDTO> GetApplicantQueryable()
{
return DataContext.Applicants
.Include(a => a.Nationality)
.Select(x => new ApplicantDTO
{
Id = x.Id,
BirthDate = x.BirthDate,
Gender = x.Gender,
FirstName = x.FirstName,
LastName = x.LastName,
OtherName = x.OtherName,
MobileNo = x.MobileNo,
Age = x.Age,
Nationality = x.Nationality.National,
Admitted = x.admitted,
Completed = x.Completed
})
.Where(a => a.Admitted == false && a.Completed == true)
.OrderBy(a => a.LastName)
.AsNoTracking();
}
But instead of just specifying the above rows, the generated SQL from profiler is
SELECT
[a].[Id], [a].[BirthDate], [a].[BirthPlace], [a].[CompleteDate],
[a].[Completed], [a].[ContentType], [a].[CreateDate],
[a].[Denomination], [a].[Disability], [a].[Email],
[a].[FirstName], [a].[Gender], [a].[HomeTown], [a].[LastName],
[a].[MarryStatus], [a].[MatureApp], [a].[MobileNo], [a].[NationalityID],
[a].[OtherName], [a].[Passport], [a].[Pin], [a].[PostalAddress],
[a].[Region], [a].[Religion], [a].[ResAddress], [a].[SerialNo],
[a].[Title], [a].[VoucherID], [a].[admitted], [a.Nationality].[National]
FROM
[Applicants] AS [a]
INNER JOIN
[Nationality] AS [a.Nationality] ON [a].[NationalityID] = [a.Nationality].[Id]
WHERE
([a].[admitted] = 0)
AND ([a].[Completed] = 1)
ORDER BY
[a].[LastName]
With all the underlying columns all included in the query.
I tried putting it in an anonymous type before casting it to the ApplicantDTO but still the same effect.
What's wrong?

Linq to entites (EF6) return latest records of each group using Row number in T-SQL server

I'm using Linq to entities to get most recent updated record of each group. But actually when I checked in sql profiler my Ling query generated many sub-query so that It really take too much time to complete. To solve this performance problem, I already wrote native T-Sql mentioned below so that I'm looking for solution to use Linq query that entity framework is generating the same my query using (ROW_NUMBER() OVER(PARTITION BY ...) . Below is my sample data :
Parent and Child tables:
Sample data of Parent and Child tables:
Below is my query result:
TSQL query:
WITH summary AS (
SELECT a.ParentId
,a.Name
,a.Email
,p.Created
,p.[Status],
ROW_NUMBER() OVER(PARTITION BY p.ParentId
ORDER BY p.Created DESC) AS rk
FROM Parent a
LEFT JOIN Child p
ON a.ParentId = P.ParentId
)
SELECT s.*
FROM summary s
WHERE s.rk = 1
My sample C# using Linq:
using (DbContext context = new DbContext())
{
return context.Parents.Where(p => p.ParentId == parentId)
.Include(a => a.Childs)
.Select(x => new ObjectDto()
{
ParentId = x.ParentId,
Status = x.Childs.OrderByDescending(a => a.Created).FirstOrDefault(p => p.ParentId).Status,
ChildName = x.Childs.OrderByDescending(a => a.Created).FirstOrDefault(p => p.ParentId).ChildName
})
.ToList();
}
There are a couple of things to improve your C# query:
using (DbContext context = new DbContext())
{
return context.Parents.Where(p => p.ParentId == parentId)
.Include(a => a.Childs)
.Select(x => new ObjectDto()
{
ParentId = x.ParentId,
Status = x.Childs.OrderByDescending(a => a.Created).FirstOrDefault(p => p.ParentId).Status,
ChildName = x.Childs.OrderByDescending(a => a.ChildName).FirstOrDefault(p => p.ParentId).ChildName
})
.ToList();
}
Firstly the Include call does nothing here as you're not just returning EF entities (and thus the lazy loading semantics don't apply).
Secondly: avoid the repeated subqueries with a let clause.
(Also the lambda passed to FirstOrDefault must be an error as it takes a Func<T, bool> which that isn't.)
Thus
using (DbContext context = new DbContext()) {
return await (from p in context.Parents
where p.ParentId == parentId
let cs = p.Childs.OrderByDescending(a => a.Created).FirstOrDefault()
select new ObjectDto {
ParentId = p.ParentId,
Status = cs.Status,
ChildName = cs.ChildName
}).ToListAsync();
}
Otherwise it looks reasonable. You would need to look at the generated query plan and see what you can do with respect to indexing.
If that doesn't work, then use a stored procedure where you have full control. (Mechanical generation of code – without a lot of work in the code generator and optimiser – can always be beaten by hand written code).

Resources