Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the "...parameterless constructors and initializers are supported..." error mean?

I'm getting this error:

Only parameterless constructors and initializers are supported in LINQ to Entities.

When trying to run this code (found this code here and made test database to play around with):

XElement xml = new XElement("contacts",
                    from c in db.Contacts
                    orderby c.ContactId
                    select new XElement("contact",
                              new XAttribute("contactId", c.ContactId),
                              new XElement("firstName", c.FirstName),
                              new XElement("lastName", c.LastName))
                    );

where db is the auto created entities object. Any ideas on how to get this to work?

like image 318
Evan Avatar asked Aug 12 '10 01:08

Evan


People also ask

What is a Parameterless constructor?

A constructor that takes no parameters is called a parameterless constructor. Parameterless constructors are invoked whenever an object is instantiated by using the new operator and no arguments are provided to new . For more information, see Instance Constructors.

Can constructors be Parameterless?

Parameter-less ConstructorWhen a constructor is declared without any parameter or argument, then it is called a parameter-less constructor. A parameter-less constructor works like a default constructor and this constructor can contain statements, or it can be empty.


2 Answers

I believe it's objecting to the fact that you're using an XElement constructor that takes parameters in your "select" clause. Since XElement doesn't have a parameterless constructor, you might need to change your code to select an anonymous type, and initialize the XElement collection after the fact.

var els = from c in db.Contacts
          orderby c.ContactID
          select new { c.ContactID, c.FirstName, c.LastName };

var xml = new XElement("contacts",
    els.ToList()
       .Select(e => new XElement("contact", 
                        new XAttribute("contactID", e.ContactID),
                        new XElement("firstName", e.FirstName),
                        new XElement("lastName", e.LastName))));

That's untested, but hopefully gives you the idea. I'm doing the EF query first, and then calling ToList() on it so that I can select the XElement collection using Linq to Objects rather than EF.

like image 83
Matt Hamilton Avatar answered Oct 03 '22 02:10

Matt Hamilton


I would rewrite it like this:

XElement xml2 = new XElement("contacts", 
                    from c in
                    ((IEnumerable<Contact>)(from c in Contacts
                    orderby c.ContactId
                    select c))
                select new XElement("contact", 
                      new XAttribute("contactId", c.ContactId),
                      new XElement("firstName", c.FirstName),
                      new XElement("lastName", c.LastName))
            );

The point is to separate LINQ execution tree from XElement instantiation. By casting LINQ query from IQueriable to IEnumerable, you will separate code LINQ will use to get data from code that is going to create your XElements.

like image 45
TTRider Avatar answered Oct 03 '22 02:10

TTRider