简体   繁体   中英

How to join two tables, and retrieve item collection using Linq

I have two tables: baswareCatalog.FlowCurrent and baswareCatalog.Doc. They both contain the attribute DocId. The Doc-table also has the attributes LastExpireDate and Status. FlowCurrent-table also has the attribute RecipientName. I want to retrieve a collection of Doc, where the DocId of the item is the same in both tables.

Furthermore, this condition must be true: flowCurrent.RecipientName.Contains(userFullName)

I tried the following, but I don't know if it is correct.

var docitemIQueryable = from flowCurrent in baswareCatalog.FlowCurrent join 
                        document in baswareCatalog.Docs on 
                        flowCurrent.DocId equals document.DocId 
                        where flowCurrent.RecipientName.Contains(userFullName) 
                        select new
                        {
                          Items = baswareCatalog
                                  .Docs
                                  .Where(b => b.DocId == flowCurrent.DocId)
                        };

The return-value is

'interface System.Linq.IQueryable<out T>'.
T is 'a' 
Anonymous Types: 'a is new {IQueryable<Doc> Items }'

How do I retrieve a collection of Doc that I can iterate over?

Without more knowledge of your table structure, you're query looks ok. At the point of the 'select' you have the two tables joined and limited by your where clause.

Inside the select new, you can assign to the new object whatever properties from the original tables you want to include.

select new
{
    DocId = flowCurrent.DocId,
    LastExpireDate = document.LastExpireDate,
    //etc
}

If you just want to get the doc items you can do this

var docitemIQueryable = from flowCurrent in baswareCatalog.FlowCurrent join 
                    document in baswareCatalog.Docs on 
                    flowCurrent.DocId equals document.DocId 
                    where flowCurrent.RecipientName.Contains(userFullName) 
                    select document;

and then you will have an iqueryable of documents

Two things:

  1. System.Linq.IQueryable is a collection that you can iterate over. You can put it in a foreach loop or do whatever you want with it. Or you can use .ToList() if you want to immediately materialize it.
  2. You're doing extra work that you don't need to do in your query. You're doing a join between FlowCurrent and Docs , but then you're taking the results and going right back to Docs again. You don't need to do that.

Assuming what you care about is just the stuff in Docs , try this:

var docitemIQueryable = from flowCurrent in baswareCatalog.FlowCurrent 
                        join document in baswareCatalog.Docs on 
                            flowCurrent.DocId equals document.DocId 
                        where flowCurrent.RecipientName.Contains(userFullName) 
                        select document;

That will give you a collection of rows with all the fields in Docs . If you need some of the stuff in FlowCurrent as well then you'll need to do something more like this:

var docitemIQueryable = from flowCurrent in baswareCatalog.FlowCurrent 
                        join document in baswareCatalog.Docs on 
                            flowCurrent.DocId equals document.DocId 
                        where flowCurrent.RecipientName.Contains(userFullName) 
                        select new {
                            document.DocId, flowCurrent.blahblah, ...
                        };

The result is a sequence of objects within items property so you need a nested loop or a SelectMany

foreach(var item in docitemIQueryable.SelectMany( x=> x.Items)){
   //do something
}

However it seems your inner selection returns just one element in which case you can skip the anonymously type object and simply select like below

select document;

and simplify the looping to

foreach(var item in docitemIQueryable){
   //do something
}

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