1

我在实体框架查询中遇到了一个非常奇怪的问题,我确实花了几个小时。

执行查询时,出现异常:

在构造函数和初始值设定项中,LINQ to Entities 仅支持属性或字段参数绑定。

说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息: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是 type 的一个属性ImageInfo,它是超级简单的类:

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

    public string ExternalUrl 
    {
        get;
        set;
    }
}

除了简单的属性分配,我显然没有做任何其他事情。为什么这个查询会失败?

4

2 回答 2

5

您当前的代码实际上是:

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
}
于 2011-07-07T10:57:19.050 回答
0

更新:有人发布了一个很好的答案,解释了我错在哪里,为什么我错了。一探究竟。

在尝试逐步在不同的计算机上重现错误后,我终于找到了问题的根源。

我正确地将Image作业确定为问题源,但是当我意识到指定类名明确解决了问题时,我非常傻眼:

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

我认为new ImageInfo对于假定匹配类型的默认构造函数的对象初始化器语法是可选的,但不知何故它是强制性的,至少对于 LINQ to Entities 而言。

于 2011-07-07T10:57:21.383 回答