LINQ to 实体无法识别方法'Char get_Chars(Int32)'方法,并且此方法无法转换为存储表达式



我是 ASP.NET MVC4和实体框架的新手。

我在我的 API 中设置了一个新方法,该方法应该获取所有具有 GET 参数 prestation 中名称prestationpartners

我在标题中收到错误,不知道如何解决:

LINQ to 实体无法识别方法"Char get_Chars(Int32("方法,并且此方法无法转换为存储表达式。

这是我的方法:

// GET: api/Partenaires_prestations
[Authorize]
[Route("api/Partenaires_prestations")]
public List<PartenaireMapItem> GetPartenairesWithPrestations()
{
    Random rnd = new Random();
    var queryString = Request.GetQueryNameValuePairs();
    var prestation = queryString.FirstOrDefault();
    return db.Partenaires
        .Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value))
        .Select(p => new PartenaireMapItem
        {
            IdPartenaire = p.IdPartenaire,
            FirstName = p.FirstName,
            LastName = p.LastName,
            NomComplet = p.LastName.ToUpper()[0] + ". " + p.FirstName,
            Type = p.Type,
            DureeMin = rnd.Next(2, 50),
            Lat = p.Lat,
            Lng = p.Lng,
            ImageUrl = p.ImageUrl,
            SeDeplace = p.SeDeplace,
            ADomicile = p.ADomicile,
            NoteGlobale = rnd.Next(1, 6),
            Prestations = new List<string>(p.PartenairePrestations.Select(y => y.Prestation.NomPrestation))
        }).ToList();
}

任何帮助将不胜感激。

感谢任何花时间阅读/回答这篇文章的人。

当您使用实体框架编写 LINQ 查询时,它会尝试将查询转换为 SQL 查询。 某些 .NET 操作无法转换为 SQL。 我认为冒犯的台词是:

p.LastName.ToUpper()[0]

我也希望你打电话给rnd。Next(( 也会导致错误。

以下是我将如何处理这种情况:

  1. 在没有违规列的情况下执行查询。 以 结束查询。ToList((。 这会将结果集加载到内存中。
  2. 循环遍历结果集并添加缺少的列。 由于结果集已加载到内存中,因此不会在 .NET 操作上引发错误。
    var result = db.Partenaires
        .Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value))
        .Select(p => new PartenaireMapItem {
            IdPartenaire = p.IdPartenaire,
            FirstName = p.FirstName,
            LastName = p.LastName,
            Type = p.Type,
            Lat = p.Lat,
            Lng = p.Lng,
            ImageUrl = p.ImageUrl,
            SeDeplace = p.SeDeplace,
            ADomicile = p.ADomicile,
            Prestations = new List(p.PartenairePrestations.Select(y => y.Prestation.NomPrestation))
        }).ToList();
    foreach (var row in result) {
        row.NomComplet = row.LastName.ToUpper()[0] + ". " + row.FirstName;
        row.DureeMin = rnd.Next(2, 50);
        row.NoteGlobale = rnd.Next(1, 6);
    }
    return result;

第二种方法是在 SQL Server 中创建存储过程。 这将消除拆分查询的需要。 这是最有效的方法,但也需要更多的工作,并且它会为您的应用程序添加更多层。 如果您预计有大量流量和数据,我才会推荐此选项。

注意:第三种方法是通过使用 来避免错误。AsEnumerable(( 或 .紧跟在 db 之后的 ToList((。帕特奈尔。 例如:

db.Partenaires.AsEnumerable().Where......或db.Partenaires.ToList().Where...

但是,此方法的危险在于它将整个表加载到内存中。 换句话说,SQL 查询将等效于 select * from Partenaires 。 然后,实体框架必须执行其他查询来检索相关表(如PartenairePrestations(中的数据,并且它将在内存中执行所有其他筛选和操作。 这是效率最低的选项。 尽管这种方法在短期内有效,但随着数据的增长,它将开始成为性能问题,所以我不建议这样做。

最新更新