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

Mar*_*arc 99 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);
    }
Run Code Online (Sandbox Code Playgroud)

我的Model类

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

    public decimal TotalPaid {
        get {
            return Payments.Sum(p => p.Amount);
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

解决了如下建议的答案:

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

        return View(debts);
    }
Run Code Online (Sandbox Code Playgroud)

Eug*_* S. 110

实体正在尝试将您的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);
}
Run Code Online (Sandbox Code Playgroud)

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


Koe*_*ten 24

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

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

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

您可以将linq语句重写为:

var debts = storeDB.Orders
                    .Where(Extensions.IsPaid())
                    .OrderByDescending(o => o.DateCreated);
Run Code Online (Sandbox Code Playgroud)

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


T G*_*pta 15

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

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

因此,总的来说,

var debts = storeDB.Orders.toList()
        .Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);
Run Code Online (Sandbox Code Playgroud)

  • 我建议要求某人在订单上创建一个toList()是危险的,因为这意味着要检索整个列表 (21认同)

Jes*_*ess 15

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

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

Ignore从DB模型映射到View模型时,解决方案是AutoMapper配置中的属性.

  1. 在数据库模型中查找[NotMapped]名称属性Foo.
  2. Foo在View Model中查找具有相同名称的属性.
  3. 如果是这种情况,请更改AutoMapper配置.加.ForMember(a => a.Foo, b => b.Ignore());


Ser*_*gan 11

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

所以代替:

public class This
{
    public long Id { get; set; }
    //...
    public virtual IEnumerable<That> Thats { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

做这个:

public class This
{
    public long Id { get; set; }
    //...
    public virtual ICollection<That> Thats { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

而且你很笨拙......两个小时就失去了愚蠢的事情.