0

I'd like to combine the results of a LINQ join between a DataTable and a List.

This works just fine:

var lpYear = (
    from a in _ds.Tables[0].AsEnumerable()
    join b in LandingPages on a["OFFERINGKEY"].ToString() equals b.Code into c
    from d in c.DefaultIfEmpty()
    where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("January 1, " + year)
    where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("December 31, " + year)
    where LandingPages.Any(x => x.Code == a["OFFERINGKEY"].ToString())
    orderby d.Title
    select new {
        title = d.Title,
        price = a["PRICE"]
    }).GroupBy(o => o.title)
    .Select(o => new { 
        total = o.Sum(p => decimal.Parse(p.price.ToString())), 
        count = o.Count(),
        title = o.Key
    }
);

And I end up with rows containing "total | count | title".

What I'd like to do is add some more columns. For example, LandingPage.URL or LandingPage.Code. I've tried like this, but it doesn't work:

var lpYear = (
    from a in _ds.Tables[0].AsEnumerable()
    join b in LandingPages on a["OFFERINGKEY"].ToString() equals b.Code into c
    from d in c.DefaultIfEmpty()
    where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("January 1, " + year)
    where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("December 31, " + year)
    where LandingPages.Any(x => x.Code == a["OFFERINGKEY"].ToString())
    orderby d.Title
    select new {
        title = d.Title,
        price = a["PRICE"],
        url = d.URL,
        code = d.Code
    }).GroupBy(o => o.title)
    .Select(o => new { 
        total = o.Sum(p => decimal.Parse(p.price.ToString())), 
        count = o.Count(),
        title = o.Key,
        url = o.Select(p=>p.url),
        code = o.Select(p=>p.code)
    }
);

This is the resulting value for url and purchased:

System.Linq.Enumerable+WhereSelectEnumerableIterator`2[<>f__AnonymousType2`3[System.String,System.Object,System.String],System.String]

The Solution (thanks to Cédric Bignon):

Place .First() at the end of my o.Select(p=>p.url) lines:

url = o.Select(p=>p.url).First(),
code = o.Select(p=>p.code).First()

Just forgot the ToList(), to enumerate the ... enumerations when you do o.Select(...)

var lpYear = (
    from a in _ds.Tables[0].AsEnumerable()
    join b in LandingPages on a["OFFERINGKEY"].ToString() equals b.Code into c
    from d in c.DefaultIfEmpty()
    where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("January 1, " + year)
    where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("December 31, " + year)
    where LandingPages.Any(x => x.Code == a["OFFERINGKEY"].ToString())
    orderby d.Title
    select new {
        title = d.Title,
        url = d.URL,
        price = a["PRICE"],
        purchased = a["PURCHASEDATE"].ToString()
    }).GroupBy(o => o.title)
    .Select(g => new { 
        total = g.Sum(p => decimal.Parse(p.price.ToString())), 
        count = g.Count(),
        title = g.Key,
        url = g.Select(p=>p.url).Distinct().Single(),
        code = g.Select(p=>p.code).Distinct().Single()
    }
);

In pure LINQ:

var lpYear = from o in (from a in _ds.Tables[0].AsEnumerable()
                        join b in LandingPages on a["OFFERINGKEY"].ToString() equals b.Code into c
                        from d in c.DefaultIfEmpty()
                        where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("January 1, " + year)
                        where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("December 31, " + year)
                        where LandingPages.Any(x => x.Code == a["OFFERINGKEY"].ToString())
                        orderby d.Title
                        select new 
                        {
                            title = d.Title,
                            url = d.URL,
                            price = a["PRICE"],
                            purchased = a["PURCHASEDATE"].ToString()
                        })
             group o by o.title into g
             select new 
             { 
                 total = g.Sum(p => decimal.Parse(p.price.ToString())), 
                 count = g.Count(),
                 title = g.Key,
                 url = (from p in g
                        select p.url).Distinct().Single(),
                 code = (from p in g
                         select p.code).Distinct().Single()
             };
4

1 に答える 1

1

, を忘れてToList()... 列挙を列挙するo.Select(...)

var lpYear = (
    from a in _ds.Tables[0].AsEnumerable()
    join b in LandingPages on a["OFFERINGKEY"].ToString() equals b.Code into c
    from d in c.DefaultIfEmpty()
    where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("January 1, " + year)
    where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("December 31, " + year)
    where LandingPages.Any(x => x.Code == a["OFFERINGKEY"].ToString())
    orderby d.Title
    select new {
        title = d.Title,
        url = d.URL,
        price = a["PRICE"],
        purchased = a["PURCHASEDATE"].ToString()
    }).GroupBy(o => o.title)
    .Select(g => new { 
        total = g.Sum(p => decimal.Parse(p.price.ToString())), 
        count = g.Count(),
        title = g.Key,
        url = g.Select(p=>p.url).Distinct().Single(),
        code = g.Select(p=>p.code).Distinct().Single()
    }
);

純粋な LINQ では:

var lpYear = from o in (from a in _ds.Tables[0].AsEnumerable()
                        join b in LandingPages on a["OFFERINGKEY"].ToString() equals b.Code into c
                        from d in c.DefaultIfEmpty()
                        where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("January 1, " + year)
                        where DateTime.Parse(a["PURCHASEDATE"].ToString()) >= DateTime.Parse("December 31, " + year)
                        where LandingPages.Any(x => x.Code == a["OFFERINGKEY"].ToString())
                        orderby d.Title
                        select new 
                        {
                            title = d.Title,
                            url = d.URL,
                            price = a["PRICE"],
                            purchased = a["PURCHASEDATE"].ToString()
                        })
             group o by o.title into g
             select new 
             { 
                 total = g.Sum(p => decimal.Parse(p.price.ToString())), 
                 count = g.Count(),
                 title = g.Key,
                 url = (from p in g
                        select p.url).Distinct().Single(),
                 code = (from p in g
                         select p.code).Distinct().Single()
             };
于 2013-01-22T15:06:21.740 に答える