Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq to sql select into a new class

My problem is that when I have following 2 queries, 1st one is not populating the CampaignID property but 2nd one does. Here is my code;

query 1;

var query = from c in _context.MCTargets
                    where c.TargetDateFrom==d1 && c.TargetDateTo<=d2
                    group c by c.MarketingCampaignID into g
                    select new MSReport{
                        CampaignID = g.Key, // CampaignID is not populated here.
                               StartDate = d1,
                               EndDate = d2
                    };

query 2;

var query2 = from c in _context.MCTargets
                    where c.TargetDateFrom == d1 && c.TargetDateTo <= d2
                    group c by c.MarketingCampaignID into g
                    select new 
                    {
                        CampaignID = g.Key,
                        StartDate = d1,
                        EndDate = d2
                    };

MSReport.cs

public class MSReport
{
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public int CampaignID { get; set; }

    public MSReport()
    {
        // CampaignID = 0 here  
        // doing something with CampaignID here like setting some calculated properties.    
    }  
 }

Thanks in advance and sorry for my poor explanation.

like image 384
Cem Avatar asked Sep 24 '12 15:09

Cem


1 Answers

When using the object initializer syntax, the values specified in the initializer are set after the constructor for the object is executed. If you need the values that you are trying to populate to be available to the constructor, you must add a form of the constructor that takes the values as arguments and populates the fields or properties itself.

In your class:

public MSReport(int campaignID, DateTime startDate, DateTime endDate)
{
       CampaignID = campaignID;
       StartDate = startDate;
       EndDate = endDate;

       // doing something with CampaignID here like setting some calculated properties.
}     

In your query:

new MSReport(g.Key, d1, d2)

This will work for Linq to SQL and Linq to Objects. For Linq to Entities a different approach must be taken.

You can execute the query with an anonymous object and then run a second query to transform it into your desired object:

var query = from c in _context.MCTargets
                  where c.TargetDateFrom==d1 && c.TargetDateTo<=d2
                  group c by c.MarketingCampaignID into g
                  select new {
                      CampaignID = g.Key,
                      StartDate = d1,
                      EndDate = d2
                  };

IEnumerable<MSReport> queryMSReports = from item in query.AsEnumerable()
                                       select new MSReport(item.CampaignID, item.StartDate, item.EndDate);

This disconnects the object from Linq to Entities and allows you to create your desired objects with a constructor that has parameters. See the LINQ to Entites 'parameterless constructor' error forum post on MSDN for more information.

Your other option is to do the query using your MSReport class and the object initializer syntax then have a Calculate method on your class that you would have to call later.

like image 73
JamieSee Avatar answered Sep 20 '22 16:09

JamieSee