-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ASP.NET MVC Core with EF Core - LEFT Outer Join in LINQ always returning top 1 record if a right side column in the WHERE clause is set to null #6499
Comments
Based on data above I tried to make a stand-alone repro. I am getting 2 results - "C3", "C4" as expected. public class Program
{
public static void Main(string[] args)
{
using (var db = new MyContext())
{
var serviceProvider = db.GetInfrastructure();
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
loggerFactory.AddConsole(LogLevel.Information);
}
using (var db = new MyContext())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
var cust1 = new Customer {CustomerName = "C1"};
var cust2 = new Customer {CustomerName = "C2"};
var cust3 = new Customer {CustomerName = "C3"};
var cust4 = new Customer {CustomerName = "C4"};
var order1 = new Order {Customer = cust1, OrderType = "V"};
var order2 = new Order {Customer = cust2, OrderType = "F"};
var order3 = new Order {Customer = cust1, OrderType = "V"};
db.AddRange(cust1, cust2, cust3, cust4, order1, order2, order3);
db.SaveChanges();
}
using (var db = new MyContext())
{
var list = (from c in db.Customers
join ord in db.Orders on c.CustomerId equals ord.CustomerId into c_o
from t in c_o.DefaultIfEmpty()
where t == null
select new CustomersViewModel() { CustName = c.CustomerName }).ToList();
}
}
}
public class MyContext : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<Customer> Customers { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;")
.EnableSensitiveDataLogging();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
public class Customer
{
public int CustomerId { get; set; }
public string CustomerName { get; set; }
}
public class Order
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; }
public string OrderType { get; set; }
}
public class CustomersViewModel
{
public string CustName { get; set; }
} Following is the SQL query generated SELECT [ord].[OrderId], [ord].[CustomerId], [ord].[OrderType], [c].[CustomerName]
FROM [Customers] AS [c]
LEFT JOIN [Orders] AS [ord] ON [c].[CustomerId] = [ord].[CustomerId]
ORDER BY [c].[CustomerId] Since the generated SQL is somewhat different, which version of EF Core are you using? I used version 1.0.0 to generate above. Also can you put break point inside controller action method to see if EF query is returning correct data or not? From results returned by EF to generating view there are other components which could contribute to bug. So it would be better to pin-point from where the bug is coming from. |
@smitpatel I'm also using EF Core 1.0. I've included a snapshot of Reference directory in my project (if that can help) in the last section of my post above. Also I've included a note in the post that I'm using Code First approach (not Db first). The query from the profiler you are getting is the same except that my profiler is using sp_executesql. Could it be a SQL Server version difference? I'm using SQL EXPRESS 2014. Moreover,
|
@saf-itpro
|
@smitpatel Thank you for clarifying (1) and (2) above. Also, I've created a sample project for testing the issue. The project can be download from GitHub here. In this ASP.NET MVC Core app the POST action method If you download the project, you will need to do the following steps to test the above unexpected results: Note: Order of these steps is important. This is a very small test project. Step2 will create a small SQL Server Db called ASPCore_Blogs. So make sure SQL Server is runing:
But that's not what happening. When you repeat this action by selecting various years years from the dropdown and click Example Data: Blogs Table Data:
Posts Table Data:
LEFT Outer JOIN in
And when you select year 1998 in the dropdown and click on Go button, the Test(...) Post action method query should return. But it's randomly returning any rows:
Models:
BlogsController:
|
@saf-itpro - Thank you for repro code. I played around with changing years and concluded following:
I have debugged queries to verify results generated by EF. EF queries are returning correct results only. You can store the results of There is some issue in the |
@smitpatel First I must acknowledge your sincere efforts to deeply look into the issue (as you must have other issues to tackle as well).
|
|
@smitpatel I had added
|
@saf-itpro - Did you verify results returned by EF query using debugger? Above behavior seems like just different behavior of same issue happening in generating the View. |
@smitpatel I did verify results returned by EF query using debugger and it indeed returns the correct data. But the |
I know this is closed and old, but the solution to this is to add keys to your entity framework. It is using the first column as key. So add these libraries to your classes: Then add the [Key] annotation . And your link to Customer should be virtual. public class Customer public class Order |
ISSUE: In my ASP.NET MVC Core app with EF Core, LEFT OUTER Join with a
Where rightColumnName == null
clause is always returning the one record that is the top row of the result. I'm using VS2015-Update3. And this is Code First project (not db first). Moreover, there is no FK relationship implemented between two tables.In my following sample data tables the customer C1 has ordered Vegetables and C2 has ordered Fruits. I want to display name of potential customers C3 and C4 who have not orders yet. So, I use an Outer Join but query always returns the first cutomer C1. It seems a bug or something wrong with my where clause.
Customers Table data:
Orders Table data:
LINQ Query to display potential customers with no orders yet:
SQL Server Profiler captures the following following SQL that returns all customers (instead of C3, C4 only):
But my view is showing only one record. Also, when I place a breakpoint at
@for (int t=0; t<Model.Count; t++)
in my view shown below, it shows only 1 at theModel.Count
:EF version installed on the project:
![capture](https://cloud.githubusercontent.com/assets/10931726/18407516/a057d494-76e0-11e6-8027-13dc02ab5f3d.PNG)
I followed the instruction from this ASP.NET official article to install the EF Core. Following is the image from my Project Reference Directory:
The text was updated successfully, but these errors were encountered: