简体   繁体   中英

LINQ - multiple left outer joins for most recent records only

I have a sample sites table with 3 child tables which can have multiple records for each sample site. I needed to do a left outer join so I would still get all the sample sites, even if they don't all have associated child records (one of the tables is empty right now). Based on some research I did on SO, I did this:

SampleSiteDataViewModel viewModel = 
            (from s in db.SAMPLESITES_EVW
            from b in db.BACTERIA_EVW.Where(b => b.FIELDSITEID == fieldSiteId).DefaultIfEmpty()
            from c in db.CHEMISTRY_EVW.Where(c => c.FIELDSITEID == fieldSiteId).DefaultIfEmpty()
            from m in db.MACROS_EVW.Where(m => m.FIELDSITEID == fieldSiteId).DefaultIfEmpty()
            where s.FIELDSITEID == fieldSiteId
            select new SampleSiteDataViewModel
                {
                    MPN_ECOLI = b.MPN_ECOLI,
                    DO_PERCENT = c.DO_PERCENT,
                    PH = c.PH,
                    TDS = c.TDS,
                    TEMP_C = c.TEMP_C,
                    OE = m.OE,
                    DESCRIP = s.DESCRIP
                }).FirstOrDefault();

However, I realized that this won't necessarily return the most recent bacteria/chemistry/macro record if there are multiple records, since it isn't a 1 to 1 relationship. So, I tried replacing .DefaultIfEmpty with .OrderByDescending(b => b.SAMPLEDATETIME).FirstOrDefault() , but I got this error:

"An expression of type 'BACTERIA_EVW' is not allowed in a subsequent from clause in a query expression with source type 'DbSet'. Type inference failed in the call to 'SelectMany'"

How can I correctly select only the most recent records while still accounting for situations where no records exist? I think it would be simpler to break it down into multiple linq queries but I'd rather do it in a single database call if possible.

ETA - this is using an ESRI Geodatabase loaded in SQL Server using an Entity Framework "code first from database" model, which (I believe) doesn't allow for navigation properties using that method.

You are almost there.

Replacing

.DefaultIfEmpty()

calls with

.OrderByDescending(b => b.SAMPLEDATETIME).FirstOrDefault()

is fine. But it changes the result type from sequence to single item, so you also need to replace the corresponding from keywords with let keywords and you are done.

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