仅支持初始值设定项,实体成员和实体导航属性

时间:2011-08-02 22:56:58

标签: linq entity-framework

我遇到了这个例外:

  

LINQ to Entities不支持指定的类型成员'付费'。   仅初始化程序,实体成员和实体导航属性   得到支持。

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .Where(o => o.Paid == false)
            .OrderByDescending(o => o.DateCreated);

        return View(debts);
    }

我的模型类

public partial class Order
{
    public bool Paid {
        get {
            return TotalPaid >= Total;
        }
    }

    public decimal TotalPaid {
        get {
            return Payments.Sum(p => p.Amount);
        }
    }

付款是一个包含字段数量的相关表格,如果我删除Where子句显示有关付款的正确信息,查询是否有效,任何线索有什么问题?

解决方案如下所示:

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .OrderByDescending(o => o.DateCreated)
            .ToList()
            .Where(o => o.Paid == false);

        return View(debts);
    }

8 个答案:

答案 0 :(得分:108)

实体正在尝试将您的Paid属性转换为SQL而不能,因为它不是表架构的一部分。

你可以做的是让实体在没有付费过滤器的情况下查询表格,然后过滤掉非付费过滤器。

public ActionResult Index()
{
    var debts = storeDB.Orders
        //.Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);

    debts = debts.Where(o => o.Paid == false);

    return View(debts);
}

当然,这意味着您将所有数据带回Web服务器并过滤其上的数据。如果要在数据库服务器上进行过滤,可以在表上创建计算列或使用存储过程。

答案 1 :(得分:23)

只需要解决类似的问题。 上述解决方案需要内存处理,这是一种不好的做法(延迟加载)。

我的解决方案是编写一个返回谓词的助手:

public static class Extensions
{
    public static Expression<Func<Order, bool>> IsPaid()
    {
        return order => order.Payments.Sum(p => p.Amount) >= order.Total;
    }
}

您可以将linq语句重写为:

var debts = storeDB.Orders
                    .Where(Extensions.IsPaid())
                    .OrderByDescending(o => o.DateCreated);

当您想重用计算逻辑(DRY)时,这很方便。 缺点是逻辑不在您的域模型中。

答案 2 :(得分:15)

  

Linq将语句转换为SQL语句并将其执行   数据库中。

现在,此转换仅适用于实体成员,初始值设定项和实体导航属性。 因此,要实现函数或获取属性比较,我们需要先将它们转换为内存列表,然后应用函数来检索数据。

因此总的来说,

var debts = storeDB.Orders.toList()
        .Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);

答案 3 :(得分:14)

此问题也可能来自数据库模型和视图模型中具有相同名称的[NotMapped]属性。

AutoMapper尝试在投影期间从数据库中选择它;并且数据库中显然不存在NotMapped属性。

当从数据库模型映射到视图模型时,解决方案是Ignore AutoMapper配置中的属性。

  1. 在数据库模型中查找名为[NotMapped]的{​​{1}}属性。
  2. 在视图模型中查找名称相同的属性Foo
  3. 如果是这种情况,请更改AutoMapper配置。添加Foo

答案 4 :(得分:11)

另一个可能的原因是因为您使用的是IEnumerable,而不是ICollection

所以而不是:

public class This
{
    public long Id { get; set; }
    //...
    public virtual IEnumerable<That> Thats { get; set; }
}

这样做:

public class This
{
    public long Id { get; set; }
    //...
    public virtual ICollection<That> Thats { get; set; }
}

而且你很笨拙......失去2个小时的愚蠢的事情。

答案 5 :(得分:2)

如果您使用 不支持EntityFramework类型 ,也可能会出现这种情况,例如unsigned int。

这是我的错误。

查看有关支持类型的更多信息: https://msdn.microsoft.com/en-us/library/ee382832(v=vs.100).aspx

这种情况有一些解决方法,由GFoley83解释: How to use unsigned int / long types with Entity Framework?

答案 6 :(得分:0)

我遇到了这个问题,因为我的成员变量只有get without set 属性

这意味着其auto calculatednot stored作为the table

中的一列

因此not exist

中的table schema
  

所以make sure所有成员变量not auto calculatedhave一个gettersetter属性

答案 7 :(得分:-1)

您的edmx和上下文模型具有一些新添加到db中的不同属性。

更新您的EDMX并正确刷新它,合并您的项目,然后再次运行。

它将解决您的问题。

关于, Ganesh Nikam