1
public partial class Table
{   
    public int TableId { get; set; }
    public Nullable<int> Num { get; set; }
    public int NbSeats { get; set; }
    public Nullable<int> R_LocationId { get; set; }
    public virtual ICollection<Availibility> Availibilities { get; set; }
    public virtual R_Locations R_Locations { get; set; }
}

public partial class Availibility
{
    public System.DateTime DayRes { get; set; }
    public Nullable<bool> Available { get; set; }
    public int TableId { get; set; }
    public virtual Table Table { get; set; }
}

I would like to implement this request with entity Framework:

select * 
from Tables join Availibilities 
    on Availibilities.TableId = Tables.TableId 
where Availibilities.Available=1
Nikhil Vartak
  • 5,002
  • 3
  • 26
  • 32
  • 1
    Possible duplicate of [Conditional Include() in Entity Framework](https://stackoverflow.com/questions/32751427/conditional-include-in-entity-framework) – Nikhil Vartak Apr 07 '18 at 23:52

2 Answers2

0

One of the slower parts of fetching data from a database is the transport of the data from the DBMS to your local process. Hence you should not transport more values than you actually plan to use.

Your Table has zero or more Availabilities. Your database implements this by giving the Availability table a foreign key to the Table that it belongs to.

So if you have a table with Id 4, which has 100 Availabilities, and you would query the Table with its Availabilities using a Join and Include you would transfer the foreign key Availability.TableId a 100 times, while you already know they will all have the value of Table.Id. You even know this value, because you asked for table with Id 4.

Hence, unless you plan to Update retrieved values, always use Select instead of querying complete classes.

Back to your question

Given a tableId, you want information of the table together with (some or all) its Availabilities.

Thanks to entity framework you don't have to use Join. If you use the collections, entity framework will do the join for you.

var tableWithAvailabilities = myDbContext.Tables
    .Where(table => table.TableId == tableId)
    .Select(table => new
    {
         // select only the properties you plan to use
         Id = table.TableId,
         Num = table.Num,
         ...
         Availabilities = table.Availabilities
             .Where(availability => ...) // if you don't want all Availabilities
             .Select(availability => new
             {
                 // again: select only the properties you plan to use

                 // not needed, you know it equals Table.TableId
                 // Id = availability.TableId,

                 Date = availability.DayRes,
                 Available = availability.Avialable,
             })
             .ToList(),
    });

Entity framework knows which Join is needed for this. One of the nicer things when using the Collections instead of a Join is that you make your database more abstract: you really are thinking of a Table that has zero or more Availabilities. It is a shortage of a DBMS that it needs two tables to implement this. If your internal tables changes, for instance the name of the foreign key, your query does not change, because you don't use the foreign key

If you are not planning to update a fetched value, then it is seldom wise to fetch

Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116
0

There is two way to filter include Entity.

  • Using a projection (See @Harald answer)
  • Using a third party library

Disclaimer: I'm the owner of the project Entity Framework Plus ( The EF+ Query IncludeFilter allow easily filter included entities. It works with EF6.x

return context.Tables
                .IncludeFilter(x => x.Availibilities .Where(c => c.Available == 1))
                .ToList();

Under the hood, the library does exactly a projection.

One limitation is all Include but now be called with IncludeFilter even if no filter is specified such as the account.

Wiki: EF+ Query Include Filter

Jonathan Magnan
  • 10,874
  • 2
  • 38
  • 60