简体   繁体   中英

How to effectively select entity and ids of related entities with Entity Framework

I use Database first approach. I have the following tables in my database:

[Country](ID, Name)
[Status](ID, Name)
[User](ID, Name)
[Object](ID, StatusID, Name)
[ObjectXCountries](ObjectID, CountryID)
[ObjectXUser](ObjectID, UserID)

Now Entity Framework creates these entities:

Country { ID, Name }
User { ID, Name }
Status { ID, Name }
Object { ID, StatusID, Status, Name, Countries, Users }

To edit a list of objects UI needs the following JSON structure:

{ 
   cnt: [ { id: 1, name: 'some country', ...}, ],
   usr: [ { id: 1, name: 'some user', ...}, ],
   st: [ { id: 1, name: 'some status', ...}, ],
   objects: [ { id: 1, name: 'some name', st: 1, cnt: [ 1, 2, 3 ], usr: [ 1, 2, 3] }, ... ] 
}

Getting a list of countries, users and statuses is trivial, but how do I get a list of object with ids connected to them? Right now I have the following code, which results in a very inefficient query:

ctx.Object.Select(rec => new ObjectDTO {
   ID = rec.ID,
   Name = rec.Name,
   StatusID = rec.StatusID,
   UserIDs = rec.Users.Select(usr => usr.ID).ToArray(),
   CountryIDs = rec.Countries.Select(cnt => cnt.ID).ToArray()
});

It translates to sql, which is dependent on the number of objects, it selects all objects and then it creates a select query for each of the objects to get a list of user ids and countries. If I have a hundred objects, it will result in 101 queries. First one to get a list of objects and 100 to get connected ids. (UPD: 201 queries, for each entity there are two additional queries to get user ids and countries ids).

Is it possible to select this info using only 3 select queries? It's easy to do in sql, but I want to know how I can do it in Entity Framework.

UPD: In SQL I would just write 3 select statements:

SELECT * FROM [Object]
SELECT * FROM [ObjectXCountries]
SELECT * FROM [ObjectXUser]

Call this query from code and then join three result sets on ObjectID. Maybe there's some way to make tables [ObjectXCountries] and [ObjectXUser] available in entity context, so I can write a similar code?

UPD: I use Entity Framework 6.2.

Ok, after googling a lot and trying out different ways, I have found a simple and working solution.

Multiple queries are the result of Lazy Loading. If I "Include" my navigational properties it will get everything in one query. This can be achieved with the following code:

ctx
.Object
.Include("Users")
.Include("Countries")
.Select(rec => new ObjectDTO {
   ID = rec.ID,
   Name = rec.Name,
   StatusID = rec.StatusID,
   UserIDs = rec.Users.Select(usr => usr.ID).ToArray(),
   CountryIDs = rec.Countries.Select(cnt => cnt.ID).ToArray()
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM