I am having a problem translating a Entity Framework 6 model to a Dto with the below code. I have used this method of converting Entities to Dtos a number of times following reading a
CodeProject article by Sacha Barber. The code was working last night so perhaps a change to the model this morning has affected the code.
Just to note the layoutTransator
object is correctly loaded from the Unity IoC container.
I have reviewed this Stackoverflow question but it does not really cover my issue.
Entity Model
Loading the entity framework model
private readonly PortalEntities ctx;
private readonly IEntityDtoTranlator<Layout, LayoutsDto> layoutTranslator;
[InjectionConstructor]
public Dal(IContextFactory<JcbManufacturingPortalEntities> factory,
IEntityDtoTranlator<Layout, LayoutsDto> layoutTransator))
{
ctx = factory.Create(ConfigurationManager.ConnectionStrings[EntityConnection].ConnectionString, EntityPassword);
this.layoutTranslator = layoutTransator;
}
public List<LayoutsDto> GetDiplayLayouts(string machineAssetName)
{
try
{
return (ctx.Layouts.Where(m => m.Hardware.AssetName.Equals(machineAssetName))
.Select(l => layoutTranslator.TranslatetoDto(l))).ToList();
}
catch (Exception ex)
{
throw;
}
}
If I break down the load code as below it works. Must be an issue with Linq calling the method.
List<Layout> layout = (ctx.Layouts.Where(m => m.Hardware.AssetName.Equals(machineAssetName))).ToList();
LayoutsDto dto = layoutTranslator.TranslatetoDto(layout.First());
Dto
public class LayoutsDto
{
[Key]
public int ID { get; set; }
[DefaultValue(0)]
[Range(0,3600000)]
public int Duration { get; set; }
[DefaultValue(0)]
public bool OutOfShift { get; set; }
public byte FlipOrder { get; set; }
public List<ScreenDto> Screens { get; set; }
}
Converter
internal class LayoutTranslator<TEntity, TDto> : IEntityDtoTranlator<Layout, LayoutsDto>
{
public LayoutsDto TranslatetoDto(Layout entity)
{
return new LayoutsDto
{
Duration = entity.DisplayDuration,
FlipOrder = entity.FlipOrder,
ID = entity.ID,
OutOfShift = entity.IsOutOfShiftScreen
};
}
public Layout TranslateToEntity(LayoutsDto dto)
{
return new Layout
{
DisplayDuration = dto.Duration,
FlipOrder = dto.FlipOrder,
ID = dto.ID,
IsOutOfShiftScreen = dto.OutOfShift
};
}
}
Exception
One point is that the TranslatetoDto(Jmp.Andon.Service.Data.Layout)
method is not in the Jmp.Andon.Models.LayoutsDto
object
LINQ to Entities does not recognize the method 'Jmp.Andon.Models.LayoutsDto TranslatetoDto(Jmp.Andon.Service.Data.Layout)' method, and this method cannot be translated into a store expression.
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert()
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassb.<GetResults>b__a()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassb.<GetResults>b__9()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at System.Lazy`1.get_Value()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Jmp.Andon.Service.Data.Dal.GetDiplayLayouts(String machineAssetName) in c:\Perforce\Development\JMP v2\Jmp.Display\Jmp.Display.Service\Data\Dal.cs:line 38