TrevorGoodchild TrevorGoodchild - 3 months ago 16
C# Question

Returning results of LINQ query

New to LINQ but this should be fairly simple.

I'm pulling a recordset of products from the DB:

ReportData= topProductsController.GetWowDetails(CurrentUser.UserId, _companyGroupCode, sector, year, string.Empty, string.Empty, string.Empty);


and from that recordset I'm trying to group the results by the product ID and count:

var productCounts = (from record in wowReportData
group record by record.ProductID into grouping
select new topProduct { Name = grouping.Key, quantity = grouping.Count() });


Here's the class I'm trying to return:

public class topProduct
{
public int quantity { get; set; }
public string Name { get; set; }

public topProduct(string productDesc, int downloadCount)
{
this.Name = productDesc;
this.quantity = downloadCount;
}
}


I'm trying to return a list of these from the function. The current error is that:


topProduct does not contain a constructor that takes 0 parameters

Answer

The reason it is failing is because you are using the property initializer way to set values to your properties, and at least in the way you called it (new topProduct {...) it will first initialize the object using the default constructor. But you don't have one.

Change to this:

var productCounts = (from record in wowReportData
                     group record by record.ProductID into grouping
                     select new topProduct(grouping.Key, grouping.Count()));

Or add a default constructor (which that is what I'd do) and then you can use it as you did

public class topProduct
{
    public int quantity { get; set; }
    public string Name { get; set; }

    //default constructor
    public topProduct() {}

    public topProduct(string productDesc, int downloadCount)
    {
        this.Name = productDesc;
        this.quantity = downloadCount;
    }
}

The use of () if for when you are initializing an object and you call a constructor - () being the default constructor (with no parameters). This one is created automatically in the case you have not created any other constructor. See here about constructors.

Now in C# 3.5 if I'm not mistaking they introduced the ability to initialize properties inline with the initialization of the object and thus to save you the pain of creating a big array of constructors for all the different options. But that is just a nice syntactic sugar for:

var obj = new Class() { Prop1 = "a", Prop2 = 2 };
        ||
var obj = new Class();
obj.Prop1 = "a";
obj.Prop2 = 2;

Then they even enabled you to remove the empty () (in the case that the constructor you are calling is the default constructor) and you turn out to have: var obj = new Class { Prop1 = "a", Prop2 = 2 }; but you can't do this if you don't have a default constructor like in your original case.