You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Define a class that has a reference navigation property that is not required. The SupervisorUser property below is an example because it, or the foreign key property SupervisorUserId property that corresponds to it doesn't have a Required attribute.
[DisplayColumn("Name"), ScaffoldTable(true), Table("ca_account_t", Schema="ca")]
public partial class Account
{
...
[Display(Order = 1)]
public virtual Chart Chart { get; set; }
[Column("FIN_COA_CD", Order = 2), Display(Name = "Chart", Order = 2), Key, Required, StringLength(2)]
public virtual string ChartCode { get; set; }
...
[Display(Name = "Supervisor User", Order = 10)]
public virtual User SupervisorUser { get; set; }
[Column("ACCT_SPVSR_UNVL_ID"), Display(Name = "Supervisor User", Order = 11), StringLength(40)]
public virtual string SupervisorUserId { get; set; }
...
}
Execute a LINQ query such as the following which does a projection, selecting only one property from the related entity through the navigation property.
var l = oc.Accounts.Select(a => new { a.Name, a.SupervisorUser.UserName } ).ToArray();
This results in the following SQL being executed in the database.
As you can see, it appears that all columns from the related table, as well as the main table, are returned in the query. I would have expected it to only return the column for the one property that was specified in the projection from that table, plus the one from the main table. I.e. the a.ACCOUNT_NM and a.SupervisorUser.PRNCPL_NM columns.
EntityFrameworkCoreProjectionBug.zip
If I run the following LINQ query that does the same thing, but, using a reference navigation property that is required, it does only query for the column that was specified in the projection.
var l = oc.Accounts.Select(a => new { a.Name, ChartName = a.Chart.Name } ).ToArray();
This results in the following SQL.
Executed DbCommand (10ms) [Parameters=[], CommandType='Text', CommandTimeout='90']
SELECT `a`.`ACCOUNT_NM`, `a.Chart`.`FIN_COA_DESC`
FROM `ca_account_t` AS `a`
INNER JOIN `ca_chart_t` AS `a.Chart` ON `a`.`FIN_COA_CD` = `a.Chart`.`FIN_COA_CD`
I don't know for sure, but, I'm guessing that the difference is that one reference property is required and the other isn't which results in either a LEFT JOIN or an INNER JOIN. The INNER JOIN case works as expected, but, the LEFT JOIN case results in pulling in extra columns. If you have tables with a lot of tables, this can significantly slow the queries down. Especially if you have CLOB fields, etc.
The issue
Extra columns are queried for in the generated SQL for non-required reference navigation properties in LINQ queries that are selecting specific fields.
Further technical details
EF Core version: 1.1.0
Operating system: Windows 10 Anniversary Update
Visual Studio version: 2015
Other details about my project setup: .NET Framework 4.6.2
The text was updated successfully, but these errors were encountered:
jemiller0
changed the title
LINQ query projection using non-required navigation property queries all columns in related table
LINQ query projection using non-required reference navigation property queries all columns in tables
Nov 28, 2016
Steps to reproduce
Define a class that has a reference navigation property that is not required. The SupervisorUser property below is an example because it, or the foreign key property SupervisorUserId property that corresponds to it doesn't have a Required attribute.
Execute a LINQ query such as the following which does a projection, selecting only one property from the related entity through the navigation property.
var l = oc.Accounts.Select(a => new { a.Name, a.SupervisorUser.UserName } ).ToArray();
This results in the following SQL being executed in the database.
As you can see, it appears that all columns from the related table, as well as the main table, are returned in the query. I would have expected it to only return the column for the one property that was specified in the projection from that table, plus the one from the main table. I.e. the
a
.ACCOUNT_NM
anda.SupervisorUser
.PRNCPL_NM
columns.EntityFrameworkCoreProjectionBug.zip
If I run the following LINQ query that does the same thing, but, using a reference navigation property that is required, it does only query for the column that was specified in the projection.
var l = oc.Accounts.Select(a => new { a.Name, ChartName = a.Chart.Name } ).ToArray();
This results in the following SQL.
I don't know for sure, but, I'm guessing that the difference is that one reference property is required and the other isn't which results in either a LEFT JOIN or an INNER JOIN. The INNER JOIN case works as expected, but, the LEFT JOIN case results in pulling in extra columns. If you have tables with a lot of tables, this can significantly slow the queries down. Especially if you have CLOB fields, etc.
The issue
Extra columns are queried for in the generated SQL for non-required reference navigation properties in LINQ queries that are selecting specific fields.
Further technical details
EF Core version: 1.1.0
Operating system: Windows 10 Anniversary Update
Visual Studio version: 2015
Other details about my project setup: .NET Framework 4.6.2
The text was updated successfully, but these errors were encountered: