Only constructors without parameters and initializers are supported in LINQ to Entities - Asp.Net MVC

Asked

Viewed 305 times

5

I’m developing an application that manages courses. The student, when entering the registration screen and clicking on the "registration" button, is associated to a course, that is, is enrolled. So far so good, only when I try to do the treatment to check if he is already enrolled in a course, because if he is enrolled can not enroll again in the same course, the system should bar, but when trying to do this treatment I came across the following error:

Only constructors without parameters and initializers are supported in LINQ to Entities

Action Registration

    //GET
    public ActionResult Inscricao()
    {
        Aluno aluno = db.Alunos.FirstOrDefault(a => a.Usuario == System.Web.HttpContext.Current.User.Identity.Name);
        if (aluno == null)
            return View("MeusCursos");

        return View(db.Cursos.Select(c => new CursoInscricoes(c, db.AlunoCursos.FirstOrDefault(ac => ac.Aluno.Equals(aluno) && ac.Curso.Equals(c)) != null)));

    }

    [HttpPost]
    public ActionResult Inscricao(int inscricaoId)
    {
        Aluno aluno;

        using (var scope = new TransactionScope())
        {
            aluno = db.Alunos.FirstOrDefault(a => a.Usuario == System.Web.HttpContext.Current.User.Identity.Name);
            if (aluno == null)
                return View("MeusCursos");

            var curso = db.Cursos.FirstOrDefault(c => c.Id == inscricaoId);
            if (curso == null)
                return View("MeusCursos");

            var alunoCurso = new AlunoCurso
            {
                Aluno = aluno,
                Curso = curso
            };

            db.AlunoCursos.Add(alunoCurso);
            db.SaveChanges();

            curso.Qtd_Vagas--;
            db.Entry(curso).State = EntityState.Modified;
            db.SaveChanges();

            scope.Complete();
        }


        return View(db.Cursos.Select(c => new CursoInscricoes(c, db.AlunoCursos.FirstOrDefault(ac => ac.Aluno.Equals(aluno) && ac.Curso.Equals(c)) != null)));

    }

My View

@model IEnumerable<MeuProjeto.Models.CursoInscricoes>

<h2>Lista de Cursos</h2>

<table class="table table-hover">
    <tr>
        <th>
            Curso
        </th>
        <th>
            Sigla
        </th>
        <th>
            Ementa
        </th>
        <th>
            Inicio
        </th>
        <th>
            Fim
        </th>
        <th>
            Turno
        </th>
        <th>
            Status
        </th>
        <th>
            Quantidade de Vagas
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
           <td>
                @Html.DisplayFor(modelItem => item.Curso.Nome_Curso)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Curso.Sigla)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Curso.Ementa)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Curso.Dt_Inicio)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Curso.Dt_Fim)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Curso.Turno)
            </td>
            <td>
                <input type="text" name="Status" id="Status" value="@Html.DisplayFor(modelItem => item.Curso.Status)" readonly class="Status" />
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Curso.Qtd_Vagas)
            </td>
            <td>
                <div class="btn-group">
                    <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Inscrição" name="detalhes" class="inscricao btn btn-success" data_toggle="modal" data_target="#modalaviso" data-inscricaoid="@item.Curso.Id" />
                    </div>
                </div>
            </td>
        </tr>

    }

</table>
<div class="form-group">

    <a href="@Url.Action("Index", "Home")"><input type="button" value="Voltar" class="btn btn-danger" /></a>

</div>
<br />


@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script>
        $(document).ready(function() {
            $(".inscricao").click(function() {
                $.ajax({
                    type: "POST",
                    url: "Inscricao/",
                    data: {inscricaoId: $(this).data("inscricaoid")},
                    success: function() {
                            $(this).attr("disabled", "disabled");
                        }
                });
            });
        });
    </script>
}

2 answers

3


Avoid doing things like this in your code:

return View(
    db.Cursos.Select(c => new CursoInscricoes(
        c, 
        db.AlunoCursos.FirstOrDefault(ac => ac.Aluno.Equals(aluno) && ac.Curso.Equals(c)) != null)
    )
);

Although it seems simpler to be succinct when creating new objects, the Entity Framework does not work very well with this construction, precisely because it tries to convert the entire expression into SQL. In your case, it is clear that the intention is not to make everything SQL, but only a part of it.

Try to separate what will be executed as SQL from what will not be. For this expression, we can do the following:

var cursos = db.Cursos.Include(c => c.AlunoCurso).ToList();
var cursoInscricoes = new List<CursoInscricoes>();
foreach (var curso in cursos) 
{
    foreach (var alunoCurso in curso.AlunoCursos)
        cursoInscricoes.Add(new CursoInscricoes {
            Curso = curso,
            AlunoCurso = alunoCurso
    });
}

return View(cursoIscricoes);

Although it is a more prolific construct, it is more correct to segment the code in this way.

1

On your return, change:

db.Cursos.Select(c => new CursoInscricoes(c, db.AlunoCursos.FirstOrDefault(ac => ac.Aluno.Equals(aluno) && ac.Curso.Equals(c)) != null))

To:

db.Cursos.ToList().Select(c => new CursoInscricoes(c, db.AlunoCursos.FirstOrDefault(ac => ac.Aluno.Equals(aluno) && ac.Curso.Equals(c)) != null))

As the error message is accusing, it is only possible to use Constructors without parameter with Linq to Entities. Then return from the database first (.ToList()) and then build the object of type CursoInscricoes.

  • I made the change @Marcusvinicius, but now I’m having this mistake: "Cannot create a constant value of type 'Meuprojeto.Models.Aluno'. Only primitive enumeration types or types are supported in this context."

Browser other questions tagged

You are not signed in. Login or sign up in order to post.