LINQ to Entities 无法识别方法“Double Parse(System.String)”方法,并且该方法无法翻译为存储表达式
当我尝试运行报告时出现错误。问题在这里: model.Referring = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question1) ? 0 : Double.Parse(m.Question1)).Average());
public class SummaryDetails
{
public int ChannelId { get; set; }
public int ChannelGroupId { get; set; }
public string Question1 { get; set; }
public string Question2 { get; set; }
public string Question3 { get; set; }
public string Question4 { get; set; }
public int OrganizationId { get; set; }
}
public ActionResult AreaManager(AreaManagerModel model)
{
model.ShowCustomerReport = false;
model.ShowSurveyReport = true;
LoadModelVariablesonPostBack(model, 8);
var _newSurveyResult = (
from ls in SessionHandler.CurrentContext.LennoxSurveyResponses
join ml in SessionHandler.CurrentContext.MailingListEntries on ls.SurveyCode equals ml.SurveyCode
join m in SessionHandler.CurrentContext.MailingLists on ml.MailingListId equals m.MailingListId
join ch in SessionHandler.CurrentContext.Channels on m.ChannelId equals ch.ChannelId
join cg in SessionHandler.CurrentContext.ChannelGroups on ch.ChannelGroupId equals cg.ChannelGroupId
join dcg in SessionHandler.CurrentContext.ChannelGroups on cg.ParentChannelGroupId equals dcg.ChannelGroupId
join ncg in SessionHandler.CurrentContext.ChannelGroups on dcg.ParentChannelGroupId equals ncg.ChannelGroupId
join pcg in SessionHandler.CurrentContext.ChannelGroups on ncg.ParentChannelGroupId equals pcg.ChannelGroupId
select new SummaryDetails {
OrganizationId = ch.OrganizationId,
Question1 = ls.Question1Answer,
Question2 = ls.Question2Answer,
Question3 = ls.Question3Answer,
Question4 = ls.Question4Answer,
ChannelId = ch.ChannelId,
ChannelGroupId = model.TMId != 0 ? cg.ChannelGroupId : model.DistrictId != 0 ? dcg.ChannelGroupId : model.AreaId != 0 ? ncg.ChannelGroupId : model.NationId != 0 ? pcg.ChannelGroupId : model.AreaId == 0 ? ncg.ChannelGroupId : model.DistrictId == 0 ? dcg.ChannelGroupId : cg.ChannelGroupId
}
);
var _newSentSurveys = (
from ml in SessionHandler.CurrentContext.MailingListEntries
join m in SessionHandler.CurrentContext.MailingLists on ml.MailingListId equals m.MailingListId
join ch in SessionHandler.CurrentContext.Channels on m.ChannelId equals ch.ChannelId
join cg in SessionHandler.CurrentContext.ChannelGroups on ch.ChannelGroupId equals cg.ChannelGroupId
join dcg in SessionHandler.CurrentContext.ChannelGroups on cg.ParentChannelGroupId equals dcg.ChannelGroupId
join ncg in SessionHandler.CurrentContext.ChannelGroups on dcg.ParentChannelGroupId equals ncg.ChannelGroupId
join pcg in SessionHandler.CurrentContext.ChannelGroups on ncg.ParentChannelGroupId equals pcg.ChannelGroupId
where (ml.EmailDate != null || ml.LetterDate != null || ml.EmailBounce == null)
select new SummaryDetails
{
OrganizationId = ch.OrganizationId,
ChannelId = ch.ChannelId,
ChannelGroupId = model.TMId != 0 ? cg.ChannelGroupId : model.DistrictId != 0 ? dcg.ChannelGroupId : model.AreaId != 0 ? ncg.ChannelGroupId : model.NationId != 0 ? pcg.ChannelGroupId : model.AreaId == 0 ? ncg.ChannelGroupId : model.DistrictId == 0 ? dcg.ChannelGroupId : cg.ChannelGroupId
}
);
if (model.ChannelId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelId == model.ChannelId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelId == model.ChannelId);
}
else if (model.TMId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.TMId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.TMId);
}
else if (model.DistrictId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.DistrictId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.DistrictId);
}
else if (model.AreaId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.AreaId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.AreaId);
}
else if (model.NationId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.NationId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.NationId);
}
else if (model.NationId == 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.OrganizationId == 8);
_newSentSurveys = _newSentSurveys.Where(p => p.OrganizationId == 8);
}
else if (model.AreaId == 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
}
else if (model.DistrictId == 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
}
else if (model.TMId == 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
}
model.SentSurveys = _newSentSurveys.Count() > 0 ? _newSentSurveys.Count() : 0;
model.CompletedSurveys = _newSurveyResult.Count() > 0 ? _newSurveyResult.Count() : 0;
model.PercentageComplete = model.SentSurveys != 0 ? (Convert.ToDouble(model.CompletedSurveys) / Convert.ToDouble(model.SentSurveys)) : 0;
if (_newSurveyResult.Count() > 0)
{
model.Referring = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question1) ? 0 : Double.Parse(m.Question1)).Average());
model.ServicePerformance = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question2) ? 0 : Double.Parse(m.Question2)).Average());
model.InstallPerformance = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question3) ? 0 : Double.Parse(m.Question3)).Average());
model.ReferringLennox = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question4) ? 0 : Double.Parse(m.Question4)).Average());
double overAllScore = CalculateOverallScore(
_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question1) ? 0 : Double.Parse(m.Question1)).Sum(),
_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question2) ? 0 : Double.Parse(m.Question2)).Sum(),
_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question3) ? 0 : Double.Parse(m.Question3)).Sum(),
_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question4) ? 0 : Double.Parse(m.Question4)).Sum(),
_newSurveyResult.Count());
model.OverallScore = Math.Round(overAllScore);
}
}
I get the error when i try to run report. The problem is here: model.Referring = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question1) ? 0 : Double.Parse(m.Question1)).Average());
public class SummaryDetails
{
public int ChannelId { get; set; }
public int ChannelGroupId { get; set; }
public string Question1 { get; set; }
public string Question2 { get; set; }
public string Question3 { get; set; }
public string Question4 { get; set; }
public int OrganizationId { get; set; }
}
public ActionResult AreaManager(AreaManagerModel model)
{
model.ShowCustomerReport = false;
model.ShowSurveyReport = true;
LoadModelVariablesonPostBack(model, 8);
var _newSurveyResult = (
from ls in SessionHandler.CurrentContext.LennoxSurveyResponses
join ml in SessionHandler.CurrentContext.MailingListEntries on ls.SurveyCode equals ml.SurveyCode
join m in SessionHandler.CurrentContext.MailingLists on ml.MailingListId equals m.MailingListId
join ch in SessionHandler.CurrentContext.Channels on m.ChannelId equals ch.ChannelId
join cg in SessionHandler.CurrentContext.ChannelGroups on ch.ChannelGroupId equals cg.ChannelGroupId
join dcg in SessionHandler.CurrentContext.ChannelGroups on cg.ParentChannelGroupId equals dcg.ChannelGroupId
join ncg in SessionHandler.CurrentContext.ChannelGroups on dcg.ParentChannelGroupId equals ncg.ChannelGroupId
join pcg in SessionHandler.CurrentContext.ChannelGroups on ncg.ParentChannelGroupId equals pcg.ChannelGroupId
select new SummaryDetails {
OrganizationId = ch.OrganizationId,
Question1 = ls.Question1Answer,
Question2 = ls.Question2Answer,
Question3 = ls.Question3Answer,
Question4 = ls.Question4Answer,
ChannelId = ch.ChannelId,
ChannelGroupId = model.TMId != 0 ? cg.ChannelGroupId : model.DistrictId != 0 ? dcg.ChannelGroupId : model.AreaId != 0 ? ncg.ChannelGroupId : model.NationId != 0 ? pcg.ChannelGroupId : model.AreaId == 0 ? ncg.ChannelGroupId : model.DistrictId == 0 ? dcg.ChannelGroupId : cg.ChannelGroupId
}
);
var _newSentSurveys = (
from ml in SessionHandler.CurrentContext.MailingListEntries
join m in SessionHandler.CurrentContext.MailingLists on ml.MailingListId equals m.MailingListId
join ch in SessionHandler.CurrentContext.Channels on m.ChannelId equals ch.ChannelId
join cg in SessionHandler.CurrentContext.ChannelGroups on ch.ChannelGroupId equals cg.ChannelGroupId
join dcg in SessionHandler.CurrentContext.ChannelGroups on cg.ParentChannelGroupId equals dcg.ChannelGroupId
join ncg in SessionHandler.CurrentContext.ChannelGroups on dcg.ParentChannelGroupId equals ncg.ChannelGroupId
join pcg in SessionHandler.CurrentContext.ChannelGroups on ncg.ParentChannelGroupId equals pcg.ChannelGroupId
where (ml.EmailDate != null || ml.LetterDate != null || ml.EmailBounce == null)
select new SummaryDetails
{
OrganizationId = ch.OrganizationId,
ChannelId = ch.ChannelId,
ChannelGroupId = model.TMId != 0 ? cg.ChannelGroupId : model.DistrictId != 0 ? dcg.ChannelGroupId : model.AreaId != 0 ? ncg.ChannelGroupId : model.NationId != 0 ? pcg.ChannelGroupId : model.AreaId == 0 ? ncg.ChannelGroupId : model.DistrictId == 0 ? dcg.ChannelGroupId : cg.ChannelGroupId
}
);
if (model.ChannelId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelId == model.ChannelId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelId == model.ChannelId);
}
else if (model.TMId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.TMId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.TMId);
}
else if (model.DistrictId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.DistrictId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.DistrictId);
}
else if (model.AreaId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.AreaId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.AreaId);
}
else if (model.NationId != 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.NationId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.NationId);
}
else if (model.NationId == 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.OrganizationId == 8);
_newSentSurveys = _newSentSurveys.Where(p => p.OrganizationId == 8);
}
else if (model.AreaId == 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
}
else if (model.DistrictId == 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
}
else if (model.TMId == 0)
{
_newSurveyResult = _newSurveyResult.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
_newSentSurveys = _newSentSurveys.Where(p => p.ChannelGroupId == model.LoggedChannelGroupId);
}
model.SentSurveys = _newSentSurveys.Count() > 0 ? _newSentSurveys.Count() : 0;
model.CompletedSurveys = _newSurveyResult.Count() > 0 ? _newSurveyResult.Count() : 0;
model.PercentageComplete = model.SentSurveys != 0 ? (Convert.ToDouble(model.CompletedSurveys) / Convert.ToDouble(model.SentSurveys)) : 0;
if (_newSurveyResult.Count() > 0)
{
model.Referring = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question1) ? 0 : Double.Parse(m.Question1)).Average());
model.ServicePerformance = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question2) ? 0 : Double.Parse(m.Question2)).Average());
model.InstallPerformance = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question3) ? 0 : Double.Parse(m.Question3)).Average());
model.ReferringLennox = Math.Round(_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question4) ? 0 : Double.Parse(m.Question4)).Average());
double overAllScore = CalculateOverallScore(
_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question1) ? 0 : Double.Parse(m.Question1)).Sum(),
_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question2) ? 0 : Double.Parse(m.Question2)).Sum(),
_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question3) ? 0 : Double.Parse(m.Question3)).Sum(),
_newSurveyResult.Select(m => string.IsNullOrEmpty(m.Question4) ? 0 : Double.Parse(m.Question4)).Sum(),
_newSurveyResult.Count());
model.OverallScore = Math.Round(overAllScore);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里的问题是您的查询正在被转换为 SQL 并在数据库上运行,而实体框架不知道如何将
Double.Parse
转换为有效的 SQL 代码。但是,您可以定义一个自定义方法来进行解析,并告诉实体框架如何将该方法转换为 SQL。具体流程如下:定义翻译
在文本编辑器中打开 *.edmx 文件,然后查找
标记。在其下方,您应该会看到
标记。在 Schema 标记内,添加以下内容:这定义了自定义 ParseDouble 函数将转换为的 Enity-SQL 代码。
创建要翻译的方法
现在我们需要在代码中定义一个匹配函数,您可以将其放入 LINQ 语句中。您的 EDMX 文件用于生成继承自 ObjectContext 的分部类。由于它是一个分部类,因此您可以向其中添加自己的方法,而无需接触生成的代码 - 只需确保类名匹配即可。
现在,您可以返回 LINQ 语句,并将
Double.Parse
的任何实例替换为YourObjectContext.ParseDouble
。由于这是实际调用Double.Parse
的实际方法,因此它将在 LINQ to Objects 调用上工作,并且由于它也在 EDMX 文件中定义,因此可以通过 LINQ to Entities 将其转换为 SQL以及。但是等等,您还没有完成!
我注意到您的 LINQ 语句还包含对
Math.Round
的调用。我不知道实体框架是否包含该方法的翻译,但如果不包含,在修复Double.Parse 的错误后,您将得到该方法的相同错误
。幸运的是,这种情况的解决方案几乎完全相同,只是 EDMX 文件中定义的函数看起来像这样:您可以使用 EDM 规范函数 查看
标记内放置的内容是有效的。The problem here is that your query is being translated into SQL and run on the database, and Entity Framework doesn't know how to translate
Double.Parse
into valid SQL code. However, you can define a custom method to do the parsing, and tell Entity Framework how to translate that method to SQL. Here's how it goes:Define the translation
Open up your *.edmx file in a text editor, and look for the
<edmx:ConceptualModels>
tag. Under that you should see a<Schema Namespace="YourModel" ...>
tag. Inside the Schema tag, add the following:This defines the Enity-SQL code that your custom ParseDouble function is going to be translated into.
Create a method to be translated
Now we need to define a matching function in code that you can put in your LINQ statement. Your EDMX file is used to generate a partial class that inherits from ObjectContext. Since it's a partial class, you can add your own methods to it without touching the generated code - just make sure the class names match.
Now you can go back to your LINQ statement, and replace any instances of
Double.Parse
withYourObjectContext.ParseDouble
. Since this is an actual method that actually callsDouble.Parse
, it will work on LINQ to Objects calls, and since it is also defined in the EDMX file, it can be translated into SQL by LINQ to Entities as well.But wait, you're not done yet!
I noticed that your LINQ statement also includes a call to
Math.Round
. I don't know off the top of my head if Entity Framework includes a translation for that method, but if it doesn't, you'll get the same error for that method after you fix the one forDouble.Parse
. Fortunately, the solution for that case is almost exactly the same, except the function defined in the EDMX file would look something like this:You can use this list of EDM Canonical Functions to see what's valid to put inside the
<DefiningExpression>
tags.