«В конструкторах и инициализаторах поддерживаются только привязки параметров свойств или полей» при использовании синтаксиса инициализатора объекта - PullRequest
1 голос
/ 07 июля 2011

У меня очень странная проблема в запросе Entity Framework, на которую я буквально потратил часы.

При выполнении запроса я получаю исключение:

В конструкторах и инициализаторах в LINQ to Entities поддерживаются только привязки параметров свойств или полей.

Описание: во время выполнения текущего веб-запроса произошло необработанное исключение.Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Сведения об исключении: System.NotSupportedException: В конструкторах и инициализаторах в LINQ to Entities поддерживаются только привязки параметров свойств или полей.

Я знаю, что эта проблема обычно возникает, когда вы вызываете конструктор с параметрами внутри запроса.Это естественно, потому что LINQ to Entities не может знать, что там происходит.

Однако мой запрос использует только синтаксис инициализатора объекта для заполнения значений, и я предполагаю, что будет вызван конструктор по умолчанию без параметров:

private static readonly Func<MyEntities, int, MessageParty> _getUserMessagePartyQuery = CompiledQuery.Compile(
    ( MyEntities ctx, int id ) =>
        ctx.Users
        .Where( u => u.ID == id )
        .Select( u => new {
            u, up = u.UserProfile, img = u.UserProfile.Image
        })
        .Select( info => new MessageParty
        {
            PartyID = id,
            Title = info.u.FullName,

            // Assignment below causes the failure:
            Image = {
                Image = info.img,
                ExternalUrl = info.up.ExternalProfileImageUrl
            },

        } ).First()
    );

Чтобы повторить, часть, вызывающая сбой:

Image = {
    Image = info.img,
    ExternalUrl = info.up.ExternalProfileImageUrl
}

Image - это свойство типа ImageInfo, которое является сверхпростым классом:

public class ImageInfo
{
    public Model.Image Image
    {
        get;
        set;
    }

    public string ExternalUrl 
    {
        get;
        set;
    }
}

Я явно не делаю ничего, кроме простых назначений свойств .Почему этот запрос не выполняется?

Ответы [ 2 ]

5 голосов
/ 07 июля 2011

Ваш текущий код эффективен:

MessageParty tmp = new MessageParty();
// Other stuff
tmp.Image.Image = info.img;
tmp.Image.ExternalUrl = info.up.ExternalProfileImageUrl;

Другими словами, он устанавливает свойства существующего ImageInfo (если он есть) вместо создания нового ImageInfo. Это называется инициализатором вложенных объектов .

Я подозреваю, что вы хотите, чтобы это было эквивалентно:

MessageParty tmp = new MessageParty();
// Other stuff
ImageInfo tmpImage = new ImageInfo();
tmpImage.Image = info.img;
tmpImage.ExternalUrl = info.up.ExternalProfileImageUrl;
tmp.Image = tmpImage;

Поэтому измените свой запрос на использование:

Image = new ImageInfo {
    Image = info.img,
    ExternalUrl = info.up.ExternalProfileImageUrl
}
0 голосов
/ 07 июля 2011

Обновление: кто-то отправил хороший ответ , объясняющий, где, почему я ошибался. Проверьте это.

После попытки воспроизвести ошибку на другом компьютере шаг за шагом я наконец нашел источник проблемы.

Я правильно определил Image назначение как источник проблемы, однако я был очень ошеломлен, когда понял, что с указанием имени класса явно решило проблему :

Image = new ImageInfo { // was: Image = {
    Image = info.img,
    ExternalUrl = info.up.ExternalProfileImageUrl
}

Я думал, что new ImageInfo будет необязательным с синтаксисом инициализатора объекта, который предполагает конструктор по умолчанию соответствующего типа, но так или иначе это обязательно, по крайней мере для LINQ to Entities.

...