LINQ to Entities no reconoce el método ‘Double Parse (System.String)’, y este método no se puede traducir a una expresión de tienda

Me sale el error cuando bash ejecutar el informe. El problema está aquí: 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); } } 

El problema aquí es que su consulta se está traduciendo a SQL y se está ejecutando en la base de datos, y Entity Framework no sabe cómo traducir Double.Parse en un código SQL válido. Sin embargo, puede definir un método personalizado para realizar el análisis sintáctico y decirle a Entity Framework cómo traducir ese método a SQL. Así es como funciona:

Definir la traducción

Abra su archivo * .edmx en un editor de texto y busque la . Debajo, debería ver una etiqueta . Dentro de la etiqueta de esquema, agregue lo siguiente:

     cast(stringvalue as Edm.Double)   

Esto define el código Enity-SQL al que se va a traducir su función ParseDouble personalizada.

Crea un método para ser traducido

Ahora tenemos que definir una función de coincidencia en el código que puede poner en su statement LINQ. Su archivo EDMX se usa para generar una clase parcial que hereda de ObjectContext. Dado que es una clase parcial, puede agregarle sus propios métodos sin tocar el código generado, solo asegúrese de que los nombres de las clases coincidan.

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

Ahora puede volver a su instrucción LINQ y reemplazar cualquier instancia de Double.Parse con YourObjectContext.ParseDouble . Dado que este es un método real que realmente llama Double.Parse , funcionará en las llamadas a LINQ to Objects, y dado que también está definido en el archivo EDMX, también puede ser traducido a SQL por LINQ a Entities.

Pero espera, ¡aún no has terminado!

Noté que su statement LINQ también incluye una llamada a Math.Round . No sé de sobra si Entity Framework incluye una traducción para ese método, pero si no lo hace, obtendrá el mismo error para ese método después de corregir el de Double.Parse . Afortunadamente, la solución para ese caso es casi la misma, excepto que la función definida en el archivo EDMX se vería así:

     Round(input)   

Puede usar esta lista de funciones de EDM Canonical para ver qué es válido poner dentro de las tags .