在构造函数和初始化器中,只支持属性或字段参数绑定.当使用对象初始化语法时

本文关键字:初始化 绑定 参数 对象 语法 字段 属性 构造函数 支持 | 更新日期: 2023-09-27 18:01:21

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

当执行查询时,我得到一个异常:

在构造函数和初始化函数中,LINQ只支持属性或字段参数绑定到实体。

描述:当前web请求执行过程中出现未处理的异常。请查看堆栈跟踪以获得有关错误及其在代码中的起源的更多信息。

Exception Details: System。NotSupportedException:在构造函数和初始化器中,LINQ to Entities只支持属性或字段参数绑定。

我知道这个问题通常发生在您在查询中调用带有参数的构造函数时。这是很自然的,因为LINQ对实体无法知道那里发生了什么。

然而,我的查询只使用对象初始化语法来填充值,并且我假设将调用默认的无参数构造函数:

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;
    }
}

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

在构造函数和初始化器中,只支持属性或字段参数绑定.当使用对象初始化语法时

您当前的代码是:

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
}

更新:有人张贴了一个很好的答案,解释在哪里,任何为什么我错了。看看吧。

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

我正确地识别出Image分配是问题源,但是当我意识到明确指定类名时,我非常惊愕:

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

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