LINQ到实体不能识别方法“双解析(System.String)”的方法,而这种方法不能被翻译成店前pression方法、种方法、而这、翻译成

2023-09-02 01:20:40 作者:我还有救吗

我得到的错误,当我尝试运行报告。问题就在这里:? model.Referring = Math.Round(_newSurveyResult.Select(M => string.IsNullOrEmpty(m.Question1)0:Double.Parse(m.Question1))平均( ));

 公共类SummaryDetails
{
    公众诠释的channelID {获得;组; }
    公众诠释ChannelGroupId {获得;组; }
    公共字符串问题1 {获得;组; }
    公共字符串问题2 {获得;组; }
    公共字符串问题3 {获得;组; }
    公共字符串Question4 {获得;组; }
    公众诠释OrganizationId {获得;组; }
}

公众的ActionResult AreaManager(AreaManagerModel模型)
{
    model.ShowCustomerReport = FALSE;
    model.ShowSurveyReport = TRUE;
    LoadModelVariablesonPostBack(型号,8);
    VAR _newSurveyResult =(
        从SessionHandler.CurrentContext.LennoxSurveyResponses LS
        加入毫升在ls.Survey code SessionHandler.CurrentContext.MailingListEntries等于ml.Survey code
        加入米SessionHandler.CurrentContext.MailingLists上ml.MailingListId等于m.MailingListId
        加入CH在SessionHandler.CurrentContext.Channels上m.ChannelId等于ch.ChannelId
        加入CG在SessionHandler.CurrentContext.ChannelGroups上ch.ChannelGroupId等于cg.ChannelGroupId
        加入DCG在SessionHandler.CurrentContext.ChannelGroups上cg.ParentChannelGroupId等于dcg.ChannelGroupId
        加入NCG在SessionHandler.CurrentContext.ChannelGroups上dcg.ParentChannelGroupId等于ncg.ChannelGroupId
        加入盈科在SessionHandler.CurrentContext.ChannelGroups上ncg.ParentChannelGroupId等于pcg.ChannelGroupId
        选择新SummaryDetails {
            OrganizationId = ch.OrganizationId,
            问题1 = ls.Question1Answer,
            问题2 = ls.Question2Answer,
            问题3 = 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 =(
        从毫升SessionHandler.CurrentContext.MailingListEntries
        加入米SessionHandler.CurrentContext.MailingLists上ml.MailingListId等于m.MailingListId
        加入CH在SessionHandler.CurrentContext.Channels上m.ChannelId等于ch.ChannelId
        加入CG在SessionHandler.CurrentContext.ChannelGroups上ch.ChannelGroupId等于cg.ChannelGroupId
        加入DCG在SessionHandler.CurrentContext.ChannelGroups上cg.ParentChannelGroupId等于dcg.ChannelGroupId
        加入NCG在SessionHandler.CurrentContext.ChannelGroups上dcg.ParentChannelGroupId等于ncg.ChannelGroupId
        加入盈科在SessionHandler.CurrentContext.ChannelGroups上ncg.ParentChannelGroupId等于pcg.ChannelGroupId
        其中(ml.EmailDate!= NULL || ml.LetterDate!= NULL || ml.EmailBounce == NULL)
        选择新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
        }
    );
    如果(model.ChannelId!= 0)
    {
        _newSurveyResult = _newSurveyResult.Where(P => p.ChannelId == model.ChannelId);
        _newSentSurveys = _newSentSurveys.Where(P => p.ChannelId == model.ChannelId);
    }
    否则如果(model.TMId!= 0)
    {
        _newSurveyResult = _newSurveyResult.Where(P => p.ChannelGroupId == model.TMId);
        _newSentSurveys = _newSentSurveys.Where(P => p.ChannelGroupId == model.TMId);
    }
    否则如果(model.DistrictId!= 0)
    {
        _newSurveyResult = _newSurveyResult.Where(P => p.ChannelGroupId == model.DistrictId);
        _newSentSurveys = _newSentSurveys.Where(P => p.ChannelGroupId == model.DistrictId);
    }
    否则如果(model.AreaId!= 0)
    {
        _newSurveyResult = _newSurveyResult.Where(P => p.ChannelGroupId == model.AreaId);
        _newSentSurveys = _newSentSurveys.Where(P => p.ChannelGroupId == model.AreaId);
    }
    否则如果(model.NationId!= 0)
    {
        _newSurveyResult = _newSurveyResult.Where(P => p.ChannelGroupId == model.NationId);
        _newSentSurveys = _newSentSurveys.Where(P => p.ChannelGroupId == model.NationId);
    }
    否则,如果(model.NationId == 0)
    {
        _newSurveyResult = _newSurveyResult.Where(P => p.OrganizationId == 8);
        _newSentSurveys = _newSentSurveys.Where(P => p.OrganizationId == 8);
    }
    否则,如果(model.AreaId == 0)
    {
        _newSurveyResult = _newSurveyResult.Where(P => p.ChannelGroupId == model.LoggedChannelGroupId);
        _newSentSurveys = _newSentSurveys.Where(P => p.ChannelGroupId == model.LoggedChannelGroupId);
    }
    否则,如果(model.DistrictId == 0)
    {
        _newSurveyResult = _newSurveyResult.Where(P => p.ChannelGroupId == model.LoggedChannelGroupId);
        _newSentSurveys = _newSentSurveys.Where(P => p.ChannelGroupId == model.LoggedChannelGroupId);
    }
    否则,如果(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;
    如果(_newSurveyResult.Count()大于0)
    {
        model.Referring = Math.Round(_newSurveyResult.Select(M => string.IsNullOrEmpty(m.Question1)0:?Double.Parse(m.Question1))平均());
        model.ServicePerformance = Math.Round(_newSurveyResult.Select(M => string.IsNullOrEmpty(m.Question2)0:?Double.Parse(m.Question2))平均());
        model.InstallPerformance = Math.Round(_newSurveyResult.Select(M => string.IsNullOrEmpty(m.Question3)0:?Double.Parse(m.Question3))平均());
        model.ReferringLennox = Math.Round(_newSurveyResult.Select(M => string.IsNullOrEmpty(m.Question4)0:?Double.Parse(m.Question4))平均());
        双overAllScore = CalculateOverallScore(
                _newSurveyResult.Select(米=> string.IsNullOrEmpty(m.Question1)?0:Double.Parse(m.Question1))。萨姆(),
                _newSurveyResult.Select(米=> string.IsNullOrEmpty(m.Question2)?0:Double.Parse(m.Question2))。萨姆(),
                _newSurveyResult.Select(米=> string.IsNullOrEmpty(m.Question3)?0:Double.Parse(m.Question3))。萨姆(),
                _newSurveyResult.Select(米=> string.IsNullOrEmpty(m.Question4)?0:Double.Parse(m.Question4))。萨姆(),
                _newSurveyResult.Count());
        model.OverallScore = Math.Round(overAllScore);
    }
}
 

解决方案

这里的问题是,你的查询被转换成SQL,并在数据库上运行,而实体框架不知道怎么翻译 Double.Parse 成有效的SQL code。但是,您可以自定义一个方法做解析,并告诉实体框架是如何把这种方法SQL。这是怎么一回事呢:

定义翻译

打开一个文本编辑器* .edmx文件,并查找< EDMX:ConceptualModels> 标记。下,你应该看到<模式命名空间=YourModel...> 标记。内部架构标记,添加以下内容:

 <作用NAME =ParseDouble的返回类型=Edm.Double>
        <参数名称=字符串值类型=Edm.String/>
        < D​​efiningEx pression>
            投(字符串值作为Edm.Double)
        < / DefiningEx pression>
    < /功能>
 

这定义了相应的实体-SQL code,你的自定义ParseDouble功能将被翻译成。

Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解

创建方法翻译

现在,我们需要定义一个匹配功能在code,你可以把你的LINQ声明。您的EDMX文件被用来生成一个分部类继承自ObjectContext的。因为它是一个局部类,您可以添加自己的方法,它无需接触产生的code - 只要确保类名的比赛

 使用System.Data.Objects.DataClasses;

公共部分类YourObjectContext
{
    ///<总结>
    ///这个方法在LINQ查询存在使用,
    ///为存根将被转换为SQL CAST语句。
    ///< /总结>
    [EdmFunction(YourModel,ParseDouble)]
    公共静态双ParseDouble(字符串,字符串值)
    {
        返回Double.Parse(字符串值);
    }
}
 

现在,你可以回到你的LINQ的语句,并更换了 Double.Parse 任何情况下,与 YourObjectContext.ParseDouble 。由于这是实际调用实际方法 Double.Parse ,它将对LINQ到对象的调用,并且因为它也是在EDMX文件中定义的,它可以被翻译到SQL通过LINQ到实体。

别急,你还没有完成!

我注意到,你的LINQ语句还包括一个呼叫 Math.Round 。我不知道把我的头顶部,如果实体框架包括翻译的方法,但如果没有,你将你修复一个用于之后得到同样的错误该方法Double.Parse 。幸运的是,这种情况下的解决方案是几乎完全一样,除了在EDMX文件中定义的函数看起来是这样的:

 <作用名称=圆的返回类型=Edm.Double>
        <参数名称=输入TYPE =Edm.Double/>
        < D​​efiningEx pression>
            轮(输入)
        < / DefiningEx pression>
    < /功能>
 

您可以使用 EDM规范函数的这个列表来看看有什么有效的把里面的< D​​efiningEx pression> 标签

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);
    }
}

解决方案

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:

    <Function Name="ParseDouble" ReturnType="Edm.Double"> 
        <Parameter Name="stringvalue" Type="Edm.String" /> 
        <DefiningExpression> 
            cast(stringvalue as Edm.Double)
        </DefiningExpression> 
    </Function>

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.

using System.Data.Objects.DataClasses;

public partial class YourObjectContext
{
    /// <summary>
    ///     This method exists for use in LINQ queries,
    ///     as a stub that will be converted to a SQL CAST statement.
    /// </summary>
    [EdmFunction("YourModel", "ParseDouble")]
    public static double ParseDouble(string stringvalue)
    {
        return Double.Parse(stringvalue);
    }
}

Now you can go back to your LINQ statement, and replace any instances of Double.Parse with YourObjectContext.ParseDouble. Since this is an actual method that actually calls Double.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 for Double.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:

    <Function Name="Round" ReturnType="Edm.Double"> 
        <Parameter Name="input" Type="Edm.Double" /> 
        <DefiningExpression> 
            Round(input)
        </DefiningExpression> 
    </Function>

You can use this list of EDM Canonical Functions to see what's valid to put inside the <DefiningExpression> tags.