mark_spencer
mark_spencer

Reputation: 393

Only parameterless constructors and initializers are supported in LINQ to Entities. (ASP.NET Web API)

I have WebAPI controller to generate xml from table data

here is code

  public class XMLController : ApiController
{
    private trackingappEntities db = new trackingappEntities();
    [HttpGet]
    public HttpResponseMessage Index()
    {
        var xdoc = new XDocument(
            new XElement("data",
                db.TimeTables.Select(w =>
                    new XElement("worker",
                        new XAttribute("id", w.INN),
                        new XElement("start", w.StartDay),
                        new XElement("pause", w.StartPause),
                        new XElement("continue", w.EndPause),
                        new XElement("end", w.EndDay)
                    )
                )
            )
        );

        return new HttpResponseMessage() { Content = new StringContent(xdoc.ToString(), Encoding.UTF8, "application/xml") };
    }
}

Here is TimeTable class

 public partial class TimeTable
{
    public int Id { get; set; }
    public string Company { get; set; }
    public string INN { get; set; }
    public string StartDay { get; set; }
    public string StartPause { get; set; }
    public string EndDay { get; set; }
    public string EndPause { get; set; }
}

But when I send request, I have this response

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

How I can fix this?

Upvotes: 1

Views: 381

Answers (1)

Matthew Haugen
Matthew Haugen

Reputation: 13286

LINQ works by inspecting the code of your function calls, rather than simply their result.

In your case, the likely solution will just be to call AsEnumerable to tell LINQ to populate each record from SQL, before calling the constructor.

var timeTables = db.TimeTables
    /*
     * Select is optional; this would improve performance for a table with many 
     * extra properties, but would have little-to-no relevant impacts if you're
     * already using them all. Similar to a SELECT * versus selecting individual
     * columns.
     */
    .Select(c => new {
        c.INN,
        c.StartDay,
        c.StartPause,
        c.EndPause,
        c.EndDay
    })
    .AsEnumerable(); // or ...await ToListAsync();

var xdoc = new XDocument(
        new XElement("data",
            timeTables.Select(w =>
                new XElement("worker",
                    new XAttribute("id", w.INN),
                    new XElement("start", w.StartDay),
                    new XElement("pause", w.StartPause),
                    new XElement("continue", w.EndPause),
                    new XElement("end", w.EndDay)
                )
            )
        )
    );

Otherwise, you can imagine LINQ trying to essentially send the logic for generating an XElement directly to SQL. Since SQL wouldn't understand the logic involved in that process, LINQ throws.

In this example, the Select call builds an anonymous type. Because it's guaranteed to have no additional logic performed in the constructor, LINQ is able to simply select those values, and populate them C#-side.

Upvotes: 5

Related Questions