asp.net - LINQ to Entities 无法识别方法 'Char get_Chars(Int32)' 方法,并且此方法无法转换为存储表达式
asp.net - LINQ to Entities does not recognize the method 'Char get_Chars(Int32)' method, and this method cannot be translated into a store expression
我是 ASP.NET MVC4 和 Entity Framework 的新手。
我在我的 API 中设置了一个新方法,该方法应该获取所有具有 prestation
且名称在 GET 参数 prestation
中找到的 partners
。
我在标题中遇到错误,不知道如何解决:
LINQ to Entities does not recognize the method 'Char get_Chars(Int32)' method, and this method cannot be translated into a store expression.
这是我的方法:
// 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();
}
如有任何帮助,我们将不胜感激。
感谢所有愿意花时间阅读 read/answer 这个 post 的人。
当您使用 Entity Framework 编写 LINQ 查询时,它会尝试将您的查询转换为 SQL 查询。某些 .NET 操作无法转换为 SQL。我认为违规行是:
p.LastName.ToUpper()[0]
我还希望您对 rnd.Next() 的调用也会导致错误。
以下是我处理这种情况的方法:
- 执行没有违规列的查询。使用 .ToList() 结束查询。这会将结果集加载到内存中。
- 遍历结果集并添加缺失的列。由于您的结果集已经加载到内存中,因此不会在 .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 服务器中创建一个存储过程。这将消除拆分查询的需要。这是最有效的方法,但也需要更多的工作,并且会为您的应用程序添加更多层。如果您希望有大量流量和数据,我只会推荐此选项。
注意:第三种方法是在 db.Partenaires 之后立即使用 .AsEnumerable() 或 .ToList() 来避免错误。例如:
db.Partenaires.AsEnumerable().Where
...或db.Partenaires.ToList().Where
...
但是,此方法的危险在于 它将整个 table 加载到内存中 。换句话说,SQL 查询将等同于 select * from Partenaires
。然后 Entity Framework 将不得不执行额外的查询以检索相关 table 中的数据(如 PartenairePrestations),并且它将在内存中执行所有其他过滤和操作。这是效率最低的选项。虽然这种方法短期内有效,但随着数据的增长,它会开始成为性能问题,所以我不推荐它。
我是 ASP.NET MVC4 和 Entity Framework 的新手。
我在我的 API 中设置了一个新方法,该方法应该获取所有具有 prestation
且名称在 GET 参数 prestation
中找到的 partners
。
我在标题中遇到错误,不知道如何解决:
LINQ to Entities does not recognize the method 'Char get_Chars(Int32)' method, and this method cannot be translated into a store expression.
这是我的方法:
// 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();
}
如有任何帮助,我们将不胜感激。
感谢所有愿意花时间阅读 read/answer 这个 post 的人。
当您使用 Entity Framework 编写 LINQ 查询时,它会尝试将您的查询转换为 SQL 查询。某些 .NET 操作无法转换为 SQL。我认为违规行是:
p.LastName.ToUpper()[0]
我还希望您对 rnd.Next() 的调用也会导致错误。
以下是我处理这种情况的方法:
- 执行没有违规列的查询。使用 .ToList() 结束查询。这会将结果集加载到内存中。
- 遍历结果集并添加缺失的列。由于您的结果集已经加载到内存中,因此不会在 .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 服务器中创建一个存储过程。这将消除拆分查询的需要。这是最有效的方法,但也需要更多的工作,并且会为您的应用程序添加更多层。如果您希望有大量流量和数据,我只会推荐此选项。
注意:第三种方法是在 db.Partenaires 之后立即使用 .AsEnumerable() 或 .ToList() 来避免错误。例如:
db.Partenaires.AsEnumerable().Where
...或db.Partenaires.ToList().Where
...
但是,此方法的危险在于 它将整个 table 加载到内存中 。换句话说,SQL 查询将等同于 select * from Partenaires
。然后 Entity Framework 将不得不执行额外的查询以检索相关 table 中的数据(如 PartenairePrestations),并且它将在内存中执行所有其他过滤和操作。这是效率最低的选项。虽然这种方法短期内有效,但随着数据的增长,它会开始成为性能问题,所以我不推荐它。