Как правильно использовать Effort с Entity Framework 6?

Я пытаюсь заставить некоторый тестовый код работать с помощью поставщика данных Effort с Entity Framework 6. То, что я пытаюсь сделать, похоже, должно быть самым простым вариантом использования, но я просто не могу понять, что Работа.

Вот мой класс DbContext:

public class CcdReductionFrameCatalogue : DbContext
    {
    public CcdReductionFrameCatalogue()
        : this("name=CcdReductionFrameCatalogue") {}

    public CcdReductionFrameCatalogue(string connectionString) : base(connectionString) {}

    public CcdReductionFrameCatalogue(DbConnection connection) : base(connection, true) {}

    public virtual DbSet<CcdFrame> CcdFrames { get; set; }
    }

Сущность POCO определяется как:

public class CcdFrame : IEquatable<CcdFrame>
    {
    public CcdFrame()
        {
        AcquisitionTimeUtc = DateTime.UtcNow;
        }

    public int Id { get; set; }
    public string Location { get; set; }
    [FitsKeyword("INSTRUME")] public string CameraName { get; set; }

    [FitsKeyword("EXPTIME")] public double ExposureTimeSeconds { get; set; }

    [FitsKeyword("SET-TEMP"), FitsKeyword("CCD-TEMP")] public double TemperatureSetpoint { get; set; }

    [FitsKeyword("NAXIS1")] public int SizeX { get; set; }

    [FitsKeyword("NAXIS2")] public int SizeY { get; set; }

    [FitsKeyword("XBINNING")] public int BinningX { get; set; }

    [FitsKeyword("YBINNING")] public int BinningY { get; set; }

    [FitsKeyword("IMAGETYP")] public string FrameType { get; set; }

    [FitsKeyword("DATE-OBS")] public DateTime AcquisitionTimeUtc { get; set; }
    [FitsKeyword("XORGSUBF")] public int SubframeOriginX { get; set; }
    [FitsKeyword("YORGSUBF")] public int SubframeOriginY { get; set; }

    // IEquatable implementation elided for clarity
    }

Атрибут [FitsKeyword] - это настраиваемый атрибут, который я определил и не должен иметь никакого отношения к Entity Framework.

В своих модульных тестах я настраивал подключение для передачи данных следующим образом, как показано в кратком руководстве Effort:

        Connection = DbConnectionFactory.CreateTransient();
        Repository = new CcdReductionFrameCatalogue(Connection);

Как только я использую какой-либо LINQ в DbSet, я получаю глупые бессмысленные сообщения об ошибках. Например, когда я передаю свой репозиторий в этот тривиальный код:

    static void AddOrUpdate(CcdFrame newFrame, CcdReductionFrameCatalogue repository)
        {
        var existingFrames = from frame in repository.CcdFrames
                             where frame.Equals(newFrame)
                             select frame;
        Console.WriteLine(existingFrames.Count());
        // ...never gets past here

Когда я запускаю этот код, я получаю:

System.NotSupportedExceptionUnable to create a constant value of type 'TA.ReductionManager.DomainObjects.CcdFrame'. Only primitive types or enumeration types are supported in this context.
   at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq)
   at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression 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.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda)
   at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.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.TranslateExpression(Expression linq)
   at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.AggregateTranslator.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.Convert()
   at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.c__DisplayClass7.b__6()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction(Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.c__DisplayClass7.b__5()
   at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1..GetEnumerator>b__0()
   at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
   at System.Linq.Enumerable.Single(IEnumerable`1 source)
   at System.Linq.Queryable.Count(IQueryable`1 source)
   at TA.ReductionManager.Specifications.FitsImporter.AddOrUpdate(CcdFrame newFrame, CcdReductionFrameCatalogue repository) in FitsImporter.cs: line 38
   at TA.ReductionManager.Specifications.FitsImporter.ImportCollection(IEnumerable`1 collection, CcdReductionFrameCatalogue repository) in FitsImporter.cs: line 29
   at TA.ReductionManager.Specifications.when_importing_fits_files_into_the_catalogue_and_there_are_no_subdirectories.b__5() in FileEnumeratorSpecs.cs: line 27

Теперь это умопомрачительно простой код LINQ, чего мне здесь не хватает?


person Tim Long    schedule 27.11.2014    source источник


Ответы (1)


Вы не можете сравнивать настраиваемые объекты в запросе LINQ. Вы должны сравнивать только примитивный тип (int, string и т. Д.).

var existingFrames = from frame in repository.CcdFrames
                     where frame.Id == newFrame.Id
                     select frame;

Вы можете получить некоторую информацию здесь: Только примитивные типы или типы перечисления поддерживаются в этом контексте

person Vsevolod Goloviznin    schedule 27.11.2014
comment
@TimLong дело в том, что EF не может перевести ваш метод Equals в SQL. Я добавил ссылку на другой вопрос, в котором есть дополнительная информация по проблеме. - person Vsevolod Goloviznin; 28.11.2014
comment
О'кей, я понимаю. Мне никогда не приходило в голову, что его нужно будет преобразовать в SQL (поскольку он отлично работает с LINQ to objects). Теперь это имеет смысл. - person Tim Long; 28.11.2014
comment
@TimLong да, сложно, когда какой-то код отлично работает с linq to objects и выдает ошибки с linq to sql - person Vsevolod Goloviznin; 28.11.2014