tags:

views:

332

answers:

2

Hello, I'm trying to join one Linq collection from Data Base and one from XML file. Is this possible? I always get: Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.

Here is my code:

MyDataContext dc = new MyDataContext();
XElement CustomData;

var pages = from p in dc.Pages
            select new
            {
                Title = p.Title,
                Slug = p.Slug,
                PageId = p.PageId.ToString()
            };

var orders = from p in CustomData.Element("pages").Elements("page")
             select new
             {
                 PageId = (string)p.Attribute("id"),
                 SortOrder = (int)p.Attribute("sortOrder")
             };


var source = from p in pages
             join o in orders
             on p.PageId equals o.PageId
             select p;

source.ToList();
+1  A: 

I don't think you need to do the join at all.

MyDataContext dc = new MyDataContext();
XElement CustomData;

var orders = CustomData.Element("pages").Elements("page")
                       .Select( o =>  new
                         {
                             PageId = p.Attribute("id").ToString(),
                             SortOrder = (int)p.Attribute("sortOrder")
                         });

var source = dc.Pages
               .Where( p => orders.Select( o => o.PageId)
                                  .Contains( p.PageId.ToString() ))
               .Select( p => new
                {
                  Title = p.Title,
                  Slug = p.Slug,
                  PageId = p.PageId.ToString()
                });
tvanfosson
Actually, my case is little bit more complicated. I reduced complexity to get problem solved and you helped me with first example. I was already trying to convert to list, but then I would get empty set after join. Problem was that Guids got converted to uppercase string and I joined on lowercase :)
Milan
This updated example is interesting but shows some error: "The type arguments for method 'System.Linq.Enumerable.Contains<TSource>(System.Collections.Generic.IEnumerable<TSource>, TSource)' cannot be inferred from the usage. Try specifying the type arguments explicitly."cause .Contains(p.PageId)
Milan
@Milan -- Is PageID an int or a string? I mistakenly assumed that you had cast PageId in orders to an int (mistook it for SortOrder). If it is an int, then try converting it to an int in order (I'll update my example).
tvanfosson
Probably ought to compare them as strings then.
tvanfosson
A: 

It doesn't look like you can do the join between the local collection (orders) and the LINQ2SQL results with deferred execution. You can execute the pages query ToList (like tvanfosson suggested originally:)) or maybe do something like this...

var source = from p in pages
             where orders.Select(o=> o.PageID).Contains(p.PageID)
             select p;

It's not quite the join you were looking for, but if you want the deferred execution of LINQ2SQL you can have it this way.

Jason Punyon
Since he's only selecting from pages, I don't think the join is necessary. I've modified my answer accordingly. Similar to yours, but it uses extension methods.
tvanfosson
My real case is little more complicated. I use one column from "orders" and I already have where ...Contains clause for something else. Anyway, thank you very much.
Milan