asp.net-LINQ to Entities无法识别方法'Char get_Chars(Int32)'方法,并且该方法无法转换为商店表达式

时间:2018-08-09 14:54:29

标签: c# asp.net entity-framework linq asp.net-mvc-4

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

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

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

  

LINQ to Entities无法识别方法'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();
}

任何帮助将不胜感激。

感谢所有愿意花时间阅读/回答这篇文章的人。

1 个答案:

答案 0 :(得分:1)

当您使用Entity Framework编写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中创建一个存储过程。这将消除拆分查询的需要。这是最有效的方法,但也需要更多工作,并且会为您的应用程序添加更多层。如果您希望获得大量流量和数据,我只会建议您使用此选项。

注意:第三种方法是通过在db.Partenaires之后立即使用.AsEnumerable()或.ToList()来避免错误。例如:

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

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