PhoKadat
PhoKadat

Reputation: 11

Performing a union in LINQ

I'm trying to get the union of these two queries but keep getting the following error:

'System.Linq.IQueryable<AnonymousType#1>' does not contain a definition for 'Union' and    the best extension method overload 'System.Linq.ParallelEnumerable.Union<TSource>(System.Linq.ParallelQuery<TSource>, System.Collections.Generic.IEnumerable<TSource>)' has some invalid arguments

The linq queries look like this:

var g = from p in context.APP_PROD_COMP_tbl
        where p.FAM_MFG == fam_mfg
        group p by new
        {
            a_B_G = p.B_G,
            a_MFG = p.MFG,
            a_PRODUCT_FAM = p.PRODUCT_FAM,
        };

var q = from p in context.APP_COMP_tbl
        where p.FAM_MFG == fam_mfg
        group p by new
        {

            a_B_G = p.a_B_G,
            a_MFG = p.a_MFG,
            a_PRODUCT_FAM = p.a_PRODUCT_FAM,

        };

var data = q.Union(g);

I've tried using IEnumerable around the queries, but it still didn't work. Not really sure where I'm going wrong at this point, although admittedly LINQ isn't something I've had a ton of exposure to.

Update:

So I've gone in a slightly different direction from what I posted earlier. After doing more research, the group by statements were from old code and no longer needed for the intended purpose. I changed those to select new statements and had no further issue with the union.

Upvotes: 1

Views: 3481

Answers (2)

RePierre
RePierre

Reputation: 9566

I think that your problem here is type mismatch: g is of type IGrouping<AnonymousType#1, APP_PROD_COMP_tbl> and q is of type IGrouping<AnonymousType#1, APP_COMP_tbl>; this is why Union gives you the error.

I am not really sure what you are trying to Union (keys of the groups or groups of data themselves) but the solution would be:

If you want to union group keys, select the keys of your groups

var data = g.Select(x => x.Key).Union(q.Select(x => x.Key));

If you want to union the groups themselves then you need to project each element from both sequences into a common type, perform the grouping and then union the groups

var g = context.APP_PROD_COMP_tbl
    .Where(p => p.FAM_MFG == fam_mfg)
    .Select(ToCommonType)   
    .GroupBy(p => new
    {
        a_B_G = p.B_G,
        a_MFG = p.MFG,
        a_PRODUCT_FAM = p.PRODUCT_FAM,
    });

var q = context.APP_COMP_tbl
    .Where(p => p.FAM_MFG == fam_mfg)
    .Select(ToCommonType)
    .GroupBy(p => new
    {

        a_B_G = p.a_B_G,
        a_MFG = p.a_MFG,
        a_PRODUCT_FAM = p.a_PRODUCT_FAM,

    });

var data = g.Union(q);

private CommonClass ToCommonType(APP_PROD_COMP_tbl item)
{
    return new CommonClass
    {
    };
}

private CommonClass ToCommonType(APP_COMP_tbl item)
{
    return new CommonClass
    {
    };
}

Upvotes: 2

Kamil Budziewski
Kamil Budziewski

Reputation: 23087

The problem is your Anonymouse types don't match:

 var a = Enumerable.Range(1, 10).Select(x => new {a = x}).AsQueryable();
 var b = Enumerable.Range(1, 10).Select(x => new {b = x}).AsQueryable();
 var c = a.Union(b);

This won't work because typeof a is not same as typeof b

 var a = Enumerable.Range(1, 10).Select(x => new {a = x}).AsQueryable();
 var b = Enumerable.Range(1, 10).Select(x => new {a = x}).AsQueryable();
 var c = a.Union(b);

But this will work, because Anonymouse types are the same.

You can try selecting same anonymouse types from your collection in q and g. Read more about Union for IQueryable

Union on IQueryAble<TSource>() accepts IQueryAble<TSource> as a parameter, so collection has to be the same type.

Upvotes: 0

Related Questions