How to do "nested" eager loading in Entity Framework? - linq

Scenario:
Employee: EmployeeId (PK) DepartmentId_FK (FK) Name and other fields
Department: DepartmentId (PK) CompanyId_FK (FK) Name and other fields
Company: CompanyId (PK) Name and other fields
How can I build a linq query that can join the three tables and returns EmployeeName, DepartmentName and CompanyName?
the following syntax does not work because there is no Navigation Property names Company on Employee.cs.
var model = DataContext.Employee
.Include("Employer")
.Include("Company");
What is the correct way to do this?

Try this :
var data = DataContext.Employees.Include("Department").Include("Department.Company");
But use this with caution as eager loading can hurt back if there is large amount of data.

Related

HasOne Relationship Differences between v5.5 and v5.6 - no longer the same?

I have a Person model with demogographic information, Orgs model with organization information and an OrgPerson model that is effectively a pivot table with additional fields. I've crated OrgPerson to extend Model instead of Pivot because it worked better with my setup.
--- Edit: table structures ---
Table: person (Model: Person)
PK: personID
(other demographic fields)
defaultOrgID (FK -> orgID) // the org that will be displayed/referenced by default
// changeable by user with multiple orgs
Table: organization (Model: Org)
PK: orgID
(other org-demographic fields)
Table: org-person (Model: OrgPerson -- functionally a pivot table)
PK: personID, orgID
(other combo-demographic fields for the person with respect to the org)
--- End of table structures edit ---
I acknowledge that the OrgPerson model is the capture of a many-to-many relationship. However, I need to be able to grab the "combo-demographic" data (stored in the OrgPerson record) for the person related to the defaultOrgID.
Because a Person can belong to multiple Orgs, I want the orgperson record for $this person but for the "default" Org as stored in $person->defaultOrgID.
My Person model had the following relation defined in v5.5 and it returned what I wanted via $person->load('orgperson') or via eager loading.
public function orgperson()
{
return $this->hasOne(OrgPerson::class, 'personID', 'personID')
->where('orgID', $this->defaultOrgID);
}
Running code like:
$person = Person::find(x);
$person->load('orgperson')
Returns a Person model with a non-null orgperson model in the relationships list.
After upgrading to v5.6 and performing some testing, I'm finding that this relation is not populating. I haven't gotten it to populate in any of my testing and I cannot find any reason why it would be different.
add a migration to give orgperson table a primary key
Schema::table('orgperson', function (Blueprint $table) {
$table->bigIncrements('id');
});
so you can do something like this
public function orgperson()
{
return $this->hasOne(OrgPerson::class, 'defaultOrgID', 'personID')
}

Laravel Eloquent on fixtures club data

I am trying to return a list of fixtures that have a team associated to them. The home team field in the fixtures table references the id on the team table and the same for the away team field:
teams
-------
id (int, primary)
name (varchar[255])
fixtures
-------
id (int, primary)
hometeam (int - references `id` on `teams`)
awayteam (int - references `id` on `teams`)
date (datetime)
I have a fixtures and team model seperately, at the moment I am only able to return the team id in the fixtures table and not the name associated to it from the team table. I believe this is because the magic models look for the same name as the field name, i.e. team instead of hometeam or awayteam.
Is there anyway I can get this to wor with eloquent or does it need an old fashioned join?
Thanks in advance
At first, Eloquent search the key with the structured name. If your foreign key is different or parent model key isn't id, you can define the fields in relation.
Ref: One To Many (Inverse)
/**
* Get the team that owns the fixture.
*/
public function team()
{
// hometeam: foreign_key
// id: parent model primary key
return $this->belongsTo('App\Team', 'hometeam', 'id');
}

Querying with Eloquent - Achieve Join

How to select records from db from a situation like below using eloquent
Tables:
Employee Table [ id,name]
Address Table [id,address_line1,employee_id,city_id]
City Table [id,name]
A Query like below does only return city id, but i need the city name as well
$employee = Employee::with('address')->get();
And My Employee Model have relationship as
public function address(){
$this->hasMany('address');
}
How to achieve the desired result so that the output of the query should give me city name from city table, based on the id from address table, without running new query for each city id to get names

Mapping multiple tables into a single Entity in Entity Framework

In in a website's database I am working on, I have two tables for example: Country & CountryLocale. The two tables contain the following columns:
Country: Id, Longitude, Latitude
CountryLocale: Id, CountryId, CountryName, CultureId
What I want is:
- When I retrieve a Country, I want the Entity to contain: CountryId, CountryName, CultureId, Latitude & Longitude.
- When I create a new Country, to insert one record into Table Country and one to Table CountryLocale.
- When I create a new Country Locale, to create a record inside CountryLocale only
etc ...
Is this attainable?
Thanks
You can use entity splitting to partially achieve that. CountryLocale would use the PK of Country as its PK. You can not insert to CountryLocale without a Country. Essentially its a single entity split into multiple tables.
modelBuilder.Entity<Country>()
.Map(mc =>
{
mc.Properties(n => new
{
n.Id,
n.Longitude,
n.Latitude
});
mc.ToTable("Country");
})
.Map(mc =>
{
mc.Properties(n => new
{
n.CountryName,
n.CultureId
});
mc.ToTable("CountryLocale");
});
use discriminator (Table per Hierarchy)
modelBuilder.Entity<CountryBase>()
.Map<Country>(c => c.Requires("Type").HasValue((int)CountryType.Country))
.Map<CountryLocale>(c => c.Requires("Type").HasValue((int)CountryType.CountryLocale));
and you can define your sub-entities as you like

How to retrieve the records from more than one table which has one to many relationship?

How to retrieve the records from more than one table which has one to many relationship.
Categories[table]
CategoryId
CategoryName
Products[table]
ProductId
CategoryId
ProductName
Description
Entites
Category[Entity]
CategoryId
CategoryName
List<Product>
Product[Entity]
ProductId
ProductName
Description
So if i give categoryId, i should get the category details with list of products associated with the category.
How to do this in linq to sql?
In linq to sql you get a reference property generated in each of your entities. This said if you do this:
Category cat = context.Categories.FirstOrDefault(x=>x.CategoryId == 1); //Where one is the //id of a random category
foreach(Product prd in cat.Products)
{
//do some logic here
}
you will get all the products.
See Include for LINQ to SQL

Resources