Querying Many to Many and Conditional Where - entity-framework-4

Within my Context file, I set up a many to many relationship between my Location class and Program class.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Location>()
.HasMany(u => u.Programs)
.WithMany(r => r.Locations)
.Map(m =>
{
m.ToTable("LocationsPrograms");
m.MapLeftKey("LocationId");
m.MapRightKey("ProgramId");
});
}
I'm creating a search/filter form where the user will need to be able to filter the locations by selecting a program.
My thought was to query the junction (M2M) table and then join that back up with the locations table.
The problem is that I don't have a class representing the M2M table other than in my OnModelCreating method.
Can I get an example on how to do this?
Basically select * from locations l join locationsprograms lp on l.LocationId = lp.locationid and lp.programid = whatever was passed in.
Thank you.

var locations = dbContext.Locations
.Where(l => l.Programs.Any(p => p.ProgramId == whateverWasPassedInId))
.ToList();
Or (works because your are filtering by the primary key property of Program):
var locations = dbContext.Programs
.Where(p => p.ProgramId == whateverWasPassedInId)
.Select(p => p.Locations)
.SingleOrDefault();

Related

EF 6 query get a single entry from other table

I am new to EF 6, then I stumble upon this query and I need to modify it to include the data from OrderDelay table. I only intend to get a single row from the database so I tried
.Include(m => m.OrderDelay.FirstOrDefault()) instead of .Include(m => m.OrderDelay). But it does not work. Any idea on how to get just a single row for this table?
var res = await _db
.Include(m => m.BusAdd)
.ThenInclude(b => b.Suburb)
.ThenInclude(s => s.State)
........
.Include(m => m.OrderDelay)
.AsNoTracking()
.SingleOrDefaultAsync(p => p.Id == id);
return res;
it does return a single row from sql the main _db.SingleOrDefaultAsync(p => p.Id == id);
if you use Include() sql-c# translation of outer join it will satisfy the main condition of the Where() and return everything that the included table is linked to.
so it will return
1 main row that satisfy the main condition of SingleOrDefaultAsync(p => p.Id == id);
multiple foreign table row
If you are pertaining to only one result _db then do not use/add multiple Include(x => x.TableName)
Just use _db.SingleOrDefaultAsync(p => p.Id == id);
But if you want to have all the Joined tables but only one of each BusAdd, Suburb, State, OrderDelay
then insert .Select() before/after SingleOrDefaultAsync() with conditions of
{
prop1 = row.prop1,
prop2 = row.prop2,
BusAdds = row.BusAdds.FirstOrDefault/SingleOrDefaultAsync(add condition here or none),
Suburbs = row.Suburbs.FirstOrDefault/SingleOrDefaultAsync(add condition here or none),
States = row.States.FirstOrDefault/SingleOrDefaultAsync(add condition here),
OrderDelay = row.OrderDelay.FirstOrDefault/SingleOrDefault(add condition here or none)
}

how to apply inner join in entityframework LINQ method syntax?

How to apply this query in entity framework method syntax
select company_id, country_id from companies, departments where companies.company_id == departments.company_id and department.departmentId = 10;
So far, I have:
var company = context.companies
.Where(com => com.Departments
.Contains(context.departments
.Where(dep => dep.department_id==_user.Department)
.FirstOrDefault()
)
)
.Select(com => new { com.company_id, com.Country })
.FirstOrDefault();
Using method based syntax, this could be as simple as;
var company = context.Companies
.Where(x => x.Departments
.Any(x => x.department_id == _user.Department)
)
.Select(x => new { x.company_id, x.Country });
This assumes your tables are set up with foreign keys giving each Company a list of Department objects. It very much depends on your data structure.

Kohana ORM table join

I have 2 tables
user (id, name, position_id)
position (id, name)
how can i join the to models, so i can do something like this.
ORM::factory('user')->position()->name
See http://kohanaframework.org/3.3/guide-api/ORM#property:_belongs_to
class Model_User extends ORM {
protected $_belongs_to = array(
'position' => array('model' => 'Position')
);
}
Now you can:
ORM::factory('User')->with('postion')->find()->position->name;
Or indeed, with an already loaded user (e.g. $user = ORM::factory('User', 1);
$user->position->name;

Selecting nested navigation properties will generate the same SQL statement when selecting separate navigation properties

I have the following repository method:-
public AccountDefinition GetCustomer2(int id)
{ var c = entities.AccountDefinitions.Where(p => p.ORG_ID == id)
.Include(a => a.SDOrganization)
.Include(a2 => a2.SiteDefinitions)
.Include(a3 => a3.SDOrganization.AaaPostalAddresses)
.Include(a4 => a4.SiteDefinitions.Select(a5 => a5.DepartmentDefinitions.Select(a6 => a6.SDUsers.Select(a7 => a7.AaaUser.AaaContactInfoes)))).SingleOrDefault();
return c; }
But when I comment some code I found that the generated SQL statement when calling the Action method will be the same:-
public AccountDefinition GetCustomer2(int id)
{ var c = entities.AccountDefinitions.Where(p => p.ORG_ID == id)
// .Include(a => a.SDOrganization)
// .Include(a2 => a2.SiteDefinitions)
.Include(a3 => a3.SDOrganization.AaaPostalAddresses)
.Include(a4 => a4.SiteDefinitions.Select(a5 => a5.DepartmentDefinitions.Select(a6 => a6.SDUsers.Select(a7 => a7.AaaUser.AaaContactInfoes)))).SingleOrDefault();
return c; }
So does this mean when I navigate to a nested Navigation property , then EF will automatically retrieve parent navigation properties also? . so for example when i write .Include(a3 => a3.SDOrganization.AaaPostalAddresses) , then there is no need to write .Include(a => a.SDOrganization)
In a nutshell yes, it has to otherwise there is no way for you to traverse to that navigation property
EG, the only way to access AccountDefinition.SDOrganization.AaaPostalAddresses is if SDOrganization is not null.
Having said that my personal preference is to make this intermediate inclusion explicit by listing it anyway. While this has no functional benefit its a reminder that this property will also be returned

MVC 4 explicitly load a many to many EF lookup and filter by both keys

I have the following in an MVC4 app. I want to filter the load by both keys, there could be many to many but both the keys together represent a unique row. The goal to to explicitly load these collections only when needed and filter by both sides of the relationship.
I have the following Entity.DBContext, it works but only for the UserId key.
context.UserProfiles.Include(o => o.CoachOfOrginizations).Where(p => p.UserId == UserId).Single()
Also this loads all of them, but of course doesnt filter at all, just showing you so you know that I set up my fluent code properly.
context.Entry(this).Collection(t => t.AdministratorOfOrginizations).Load();
modelBuilder.Entity<UserProfile>()
.HasMany(p => p.CoachOfOrginizations)
.WithMany(t => t.Coaches)
.Map(mc =>
{
mc.ToTable("OrganizationCoaches");
mc.MapLeftKey("UserProfileID");
mc.MapRightKey("OrganizationID");
});
CoachOfOrginizations is the following property on UserProfile.
public ICollection<Organization> CoachOfOrginizations { get; set; }
What i would like is to filter my original .Include above based on Organization.ID (the other key) and the currently used key p.UserId. I've tried the following and it doesn't work, any advice? "this" is the UserProfile object.
context.Entry(this)
.Collection(b => b.CoachOfOrginizations)
.Query()
.Where(p => p.ID == orgID)
.Load();
You can do both filtering in a single query. See conditional includes.
var query = context.UserProfiles
.Where(p => p.UserId == UserId)
.Select(p => new { p, Orgs = p.CoachOfOrginizations.Where(o => o.ID == orgID) });
var profiles = query.AsEnumerable().Select(a => a.p);

Resources