简体   繁体   中英

How do I join 2 dbSets in a repository relationship request using Linq / Entity framework

Let's say I have the following code:

    public ActionResult ListByJames(int jamesID, int page = 1, string sort = "Name", bool desc = false)
    {
        IEnumerable<Bob> orderedBobs = bobRepository.SortByColumnName(sort, desc);
        IEnumerable<Bob_JamesRelationship> bobRelations = bobRelationshipRepository.Relationships;
        James james = jamesRepository.GetByID(jamesID);

        // At the moment, the following returning model just returns a 
        // list of Bobs, but I need to return a list of bobs that are 
        // related to the James that is passed through

        ListViewModel<Bob> model = new ListViewModel<Bob>
        {
            Items = orderedBobs
                .Skip((page - 1) * PageSize)
                .Take(PageSize),
            PagingInfo = new PagingInfo
            {
                CurrentPage = page,
                ItemsPerPage = PageSize,
                TotalItems = orderedBobs.Count(),
                Sort = sort,
                Desc = desc
            }
        };
        return View("_List", model);
    }

I need to make a SQL statement like this:

SELECT
    *
FROM 
    James j
JOIN
    Bob_JamesRelationships r ON
    j.Id = r.JamesID
JOIN
    Bobs b ON
    b.Id = r.BobID

but in the style of my C# code using Linq

Note that the following lines

        IEnumerable<Bob> orderedBobs = bobRepository.SortByColumnName(sort, desc);
        IEnumerable<Bob_JamesRelationship> bobRelations = bobRelationshipRepository.Relationships;
        James james = jamesRepository.GetByID(jamesID);

contain all of the information required to get the required set of Bobs back.

A James is related to a Bob via a Bob_JamesRelationship... I also have 3 SQL tables that represent these too.

How do I go about doing this?

All collections must be IQueryable if you want them to be combined into one query. IEnumerable is always an in-memory object that has no connection to a query provider. IQueryable has an expression tree that its query provider can translate into the query language of the underlying data store. Expression trees from different IQueryable instances with the same provider can be combined into one by compose methods like Join .

So the first thing to do is return IQueryable<T> from your repositories. Second, make sure they share the same context instance. Then you can do things like

from bo in orderedBobs
join br in bobRelations on bo.Id equals br.BobId
join j in James on br.JamesId equals j.Id
where j.Id == jamesId
select new { bo, br, j }

and see it translated into one SQL statement. I can't judge whether this is a small step or a giant leap for your current architecture, but it's the way to go anyhow.

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