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

5

I'm developing an application that manages courses. The student, when entering the inscription screen and clicking on the "enrollment" button, is associated to a course, that is, is enrolled. So far so good, only when I try to check if he is already enrolled in a course, because if he is enrolled he can not sign up again in the same course, the system should stop, but when trying to do this treatment me I encountered the following error:

  

Only parameterless constructors and initializers are supported in LINQ to Entities

Action Enrollment

    //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>
}
    
asked by anonymous 06.06.2015 / 18:17

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 in creating new objects, the Entity Framework does not work very well with this construct, precisely because it attempts 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 run 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 elaborate construction, it is more appropriate to segment the code in this way.

    
08.06.2015 / 00:40
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))

Because the error message is acknowledging, you can only use parameterless constructors with Linq to Entities. Then return the bank first (% with%) and then build the object of type .ToList() .

    
06.06.2015 / 20:21