【问题标题】:Unable to create a constant value of type 'AddressModel'. Only primitive types or enumeration types are supported in this context无法创建“AddressModel”类型的常量值。此上下文仅支持原始类型或枚举类型
【发布时间】:2016-06-24 16:33:42
【问题描述】:

在下面的 EF 查询中,每当将子联系人地址字段分配给 TaxReceiptsWithChargesModel 的 Address 属性时,我都会收到错误消息:

“无法创建'AddressModel'类型的常量值”

如果我注释掉分配地址的行,则不会发生错误。可能是什么问题?

编辑:通常,我在其他地方看到的这个问题的原因与使用 contains 或 equals LINQ 方法有关,但这个特定问题的原因似乎在其他地方。

以下是相关的代码部分:

            //GetChildContactAddress
            var childContactAddress = lgcCcpModel.ChildContacts
                .Where(cc => cc.UUID == ltrm.ChildContactId)
                .Select(cc => new AddressModel()
                {
                    Address1 = cc.Address.STREET,
                    City = cc.Address.CITY,
                    Province = cc.Address.PROVINCE,
                    PostalCode = cc.Address.POSTALCODE
                }).FirstOrDefault();

        //Create the Tax Receipt Model with the Charge List
        return unitOfWork.LegacyTaxReceiptStore.GetQuery()
            .Where(ltr => ltr.LegacyTaxReceiptId ==         ltrm.LegacyTaxReceiptId)
            .Select(c => new TaxReceiptsWithChargesModel()
            {
                LegacyTaxReceiptId = ltrm.LegacyTaxReceiptId,
                ChildContactId = ltrm.ChildContactId,
                ChildContact = ltrm.ChildContact,
                EmailAddress = ltrm.EmailAddress,
                ChildId = ltrm.ChildId,
                ChildName = ltrm.ChildName,
                ChargesTotal = ltrm.ChargesTotal,
                TaxReceiptAmount = ltrm.TaxReceiptAmount.Value,
                TaxReceiptYear = ltrm.TaxReceiptYear,
                Address = childContactAddress,
                ReceiptNumber = $"{ltrm.TaxReceiptYear}-{ltrm.LegacyTaxReceiptId.ToString().PadLeft(6, '0')}",
                Charges = taxReceiptChargesModelList,
            }).FirstOrDefault();


public class TaxReceiptsWithChargesModel : ITaxReceiptsModel
    {
        public int LegacyTaxReceiptId { get; set; }
        public string ChildContactId { get; set; }
        public string ChildContact { get; set; }
        public string EmailAddress { get; set; }
        public IAddressModel Address { get; set; }
        public decimal? OpeningBalance { get; set; }
        public decimal? InvoicesTotal { get; set; }
        public decimal? PaymentsTotal { get; set; }
        public string ChildId { get; set; }
        public string ChildName { get; set; }
        public decimal? ChargesTotal { get; set; }
        public decimal? TaxReceiptAmount { get; set; }
        public string State { get; set; }
        public int TaxReceiptYear { get; set; }
        public string ReceiptNumber { get; set; }
        public int? BinaryDocumentId { get; set; }
        public List<TaxReceiptsChargesModel> Charges { get; set; }
    }

public interface IAddressModel
    {
        string Address1 { get; set; }
        string Address2 { get; set; }
        string City { get; set; }
        string Country { get; set; }
        string PostalCode { get; set; }
        string Province { get; set; }
    }

【问题讨论】:

    标签: c# sql entity-framework asp.net-mvc-4


    【解决方案1】:

    这是因为childContactAddress 对象(以及taxReceiptChargesModelList)已经在内存中,当您尝试在第二个查询的投影中分配一个复杂对象时,Linq 提供程序无法将该对象转换为 SQL。一种选择是调用AsEnumerable扩展方法:

      return unitOfWork.LegacyTaxReceiptStore.GetQuery()
            .Where(ltr => ltr.LegacyTaxReceiptId ==ltrm.LegacyTaxReceiptId)
            .AsEnumerable()
            .Select(c => new TaxReceiptsWithChargesModel()
            {
                LegacyTaxReceiptId = ltrm.LegacyTaxReceiptId,
                ChildContactId = ltrm.ChildContactId,
                ChildContact = ltrm.ChildContact,
                EmailAddress = ltrm.EmailAddress,
                ChildId = ltrm.ChildId,
                ChildName = ltrm.ChildName,
                ChargesTotal = ltrm.ChargesTotal,
                TaxReceiptAmount = ltrm.TaxReceiptAmount.Value,
                TaxReceiptYear = ltrm.TaxReceiptYear,
                Address = childContactAddress,
                ReceiptNumber = $"{ltrm.TaxReceiptYear}-{ltrm.LegacyTaxReceiptId.ToString().PadLeft(6, '0')}",
                Charges = taxReceiptChargesModelList, 
            }).FirstOrDefault();
    

    更新

    你的问题也可以这样解决:

    var result=unitOfWork.LegacyTaxReceiptStore.GetQuery()
                .FirstOrDefault(ltr => ltr.LegacyTaxReceiptId ==ltrm.LegacyTaxReceiptId);
    
    return new TaxReceiptsWithChargesModel()
            {
                LegacyTaxReceiptId = result.LegacyTaxReceiptId,
                ChildContactId = result.ChildContactId,
                ChildContact = result.ChildContact,
                EmailAddress = result.EmailAddress,
                ChildId = result.ChildId,
                ChildName = result.ChildName,
                ChargesTotal = result.ChargesTotal,
                TaxReceiptAmount = result.TaxReceiptAmount.Value,
                TaxReceiptYear = result.TaxReceiptYear,
                Address = childContactAddress,
                ReceiptNumber = $"{result.TaxReceiptYear}-{result.LegacyTaxReceiptId.ToString().PadLeft(6, '0')}",
                Charges = taxReceiptChargesModelList,
            };
    

    【讨论】:

    • 我尝试在初始查询后分配地址,但产生了相同的结果。我会看看你的第一个建议和上面提到的另一个。谢谢!
    • 这应该是由于字符串插值,我认为 Linq to Entities 尚不支持。我建议尝试第一个解决方案,ToString 也不支持
    • 感谢您的帮助!解决方案 1 和 3 效果很好。
    【解决方案2】:

    您必须应用 [Serializable()] 装饰器,但不能对接口执行此操作。

    相反,使用 ISerializable {}

    实现您的自定义接口

    下面已经回答了一个类似的问题,这篇文章的功劳归于 Oded。

    Why are interfaces not [Serializable]?

    干杯

    【讨论】:

      【解决方案3】:

      你能告诉我使用接口作为模型属性有什么意义吗? Microsoft 不鼓励将 in 接口用作模型属性。您可以使用 getter 和 setter 方法来限制您的属性的更改。 看到这个帖子 https://stackoverflow.com/a/8455558/2173098

      【讨论】:

      • 公平,好点。这是一个继承的代码库。也许我们可以考虑稍后对其进行更改。
      猜你喜欢
      • 1970-01-01
      • 2013-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多