You don't need JOINs if your classes have proper relations. ORMs like Entity Framework allow you to work with classes, not tables. If you have a ClientFacility
class with a Triggers
collection, EF itself will generate the proper JOINs when you load a ClientFacility
.
The Relationships article in the EF Core documentation shows how to define relationships in general so you don't have to deal with keys and JOINs in queries.
The Blog/Posts example shows how to handle 1:M relations:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public string Title {get;set;}
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
With these classes, if you want to find all the posts of a blog you can write :
var posts=_context.Posts.Where(p=>p.Blog.Title="Bananas");
It's EF's job to generate the Blogs INNER JOIN Posts ON Blogs.BlogID=Posts.BlogId
clause.
In the question's case it seems there's a many-to-many relation between ClientFacility
and Trigger
. EF Core 6 allows modelling many-to-many relations without also modelling the bridge class ClientFacilityTrigger
.
Assuming you have :
public class ClientFacility
{
public long ClientFacilityId {get;set;}
public List<Trigger> Triggers {get;set}
}
public class Trigger
{
public long TriggerId {get;set;}
public string Event {get;set;}
public bool IsDeleted {get;set;}
}
public class MyContext:DbContext
{
public DbSet<Facility> Facilities {get;set;}
public DbSet<Trigger> Triggers {get;set;}
}
You could retrieve a facility's triggers with :
var results=from facility in _context.Facilities
where facility.ClientFacilityId=1
from trigger in facility.Triggers
select new {
trigger.Event,
trigger.IsDeleted,
...
};
A DbContext's OnModelBuilding
method can be used to define more complex relations, eg using composite keys or columns that don't follow naming conventions.
This clause makes me suspect there are more entities, Client
and Facility
and ClientFacility
links them to Trigger
. This can be modelled as well :
public class Client
{
public long ClientId {get;set;}
public List<ClientFacility> Facilities {get;set;}
}
public class Facility
{
public long FacilityId {get;set;}
public List<ClientFacility> Facilities {get;set;}
}
public class ClientFacility
{
public long ClientFacilityId {get;set;}
public long ClientId {get;set;}
public long FacilityId {get;set;}
public Client Client{get;set;}
public Facility Facility {get;set;}
}