C# 使用对象初始值设定项语法时,“在构造函数和初始值设定项中,仅支持属性或字段参数绑定”

C# 使用对象初始值设定项语法时,“在构造函数和初始值设定项中,仅支持属性或字段参数绑定”,c#,entity-framework,entity-framework-4,linq-to-entities,object-initializers,C#,Entity Framework,Entity Framework 4,Linq To Entities,Object Initializers,我在实体框架查询中遇到了一个非常奇怪的问题,我实际上花了几个小时在这个问题上 执行查询时,我得到一个异常: 在构造函数和初始值设定项中,LINQ只支持属性或字段参数绑定到实体 描述:执行当前web请求期间发生未处理的异常。请查看堆栈跟踪以了解有关错误的更多信息以及错误在代码中的起源 异常详细信息:System.NotSupportedException:在构造函数和初始值设定项中,LINQ中只支持属性或字段参数绑定到实体 我知道这个问题通常发生在使用查询中的参数调用构造函数时。这是很自然的,因为

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

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

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

描述:执行当前web请求期间发生未处理的异常。请查看堆栈跟踪以了解有关错误的更多信息以及错误在代码中的起源

异常详细信息:System.NotSupportedException:在构造函数和初始值设定项中,LINQ中只支持属性或字段参数绑定到实体

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

但是,我的查询仅使用对象初始值设定项语法来填充值,我假设将调用默认的无参数构造函数:

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是ImageInfo类型的属性,它是uber simple类:

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
}

您当前的代码实际上是:

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
}
更新:有人贴了一条解释我错在哪里,为什么我错了的帖子。过来看。 在尝试在不同的计算机上一步一步地重现错误之后,我终于找到了问题的根源

我正确地确定图像分配是问题的根源,但是当我意识到指定类名显式地解决了问题时,我大吃一惊:

我原以为新的ImageInfo对于假定匹配类型的默认构造函数的对象初始值设定项语法是可选的,但不知何故它是强制性的,至少对于LINQ to实体是如此。

Update:有人发布了一条解释我错在哪里、为什么错在哪里的帖子。过来看。 在尝试在不同的计算机上一步一步地重现错误之后,我终于找到了问题的根源

我正确地确定图像分配是问题的根源,但是当我意识到指定类名显式地解决了问题时,我大吃一惊:


我原以为新的ImageInfo对于采用匹配类型的默认构造函数的对象初始值设定项语法是可选的,但不知何故它是强制性的,至少对于LINQ to实体来说是如此。

您是个圣人。我又花了一个小时摆弄代码,已经找到了这个修复程序,我正要发布它,但是你在我之前就成功地完成了,并且给出了解释!非常感谢,你是个圣人。我又花了一个小时摆弄代码,已经找到了这个修复程序,我正要发布它,但是你在我之前就成功地完成了,并且给出了解释!非常感谢。