【问题标题】:Entity query criteria with static instance members具有静态实例成员的实体查询条件
【发布时间】:2016-08-31 08:23:31
【问题描述】:

我正在尝试创建一个类似于订单状态历史表的审计跟踪。这样,Orders 可以有许多 OrderState,以及一个指向最新历史项目的 State。保存更新时到目前为止一切顺利。当我尝试像使用枚举一样查询时会出现问题:

public class OrderState
{
    public static OrderState Placed = new OrderState("Placed", 1, 1);
    public static OrderState Accepted = new OrderState("Accepted", 10, 2);
    public static OrderState Cancelled = new OrderState("Cancelled", 20, 3);
    public static OrderState Completed = new OrderState("Completed", 30, 4);

    protected OrderState()
    {
    }

    public OrderState(string name, int order, int id)
    {
        Name = name;
        Order = order;
        Id = id;
    }

    public int Id { get; set; }
    public string Name { get; protected set; }
    public int Order { get; protected set; }



    public static bool operator == (OrderState state1, OrderState state2)
    {
        if (ReferenceEquals(state1, null))
        {
            return ReferenceEquals(state2, null);
        }
        return state1.Equals(state2);
    }

    public static bool operator !=(OrderState state1, OrderState state2)
    {
        return !(state1 == state2);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }
        if (ReferenceEquals(this, obj))
        {
            return true;
        }
        if (!(obj is OrderState))
        {
            return false;
        }
        return Equals((OrderState)obj);
    }

    public virtual bool Equals(OrderState other)
    {
        return other.Id.Equals(Id);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((Id.GetHashCode())*397) ^ Order;
        }
    }


}

订单类

public class Order
{
    public Order()
    {
        Progress(OrderState.Placed);
    }
    public int Id { get; set; }

    public virtual OrderState State
    {
        get { return States.OrderByDescending(x => x.State.Order).FirstOrDefault()?.State; }
    }

    public void Progress(OrderState state)
    {
        if (States.All(x => x.State != state))
        {
            States.Add(new OrderStateHistory()
            {
                Order = this,
                State = state
            });
        }
    }

    public virtual ICollection<OrderStateHistory> States { get; set; } = new List<OrderStateHistory>();
}

在我的代码中,这样的事情可以正常工作: order.Progress(OrderState.Accepted);if (order.State == OrderState.Accepted)

但是,我想访问的是 Where(x =&gt; x.State.Equals(OrderState.Accepted))Where(x =&gt; x.State == OrderState.Accepted)

不幸的是,任何一个条件都会产生“LINQ to Entities 不支持指定类型成员“状态”。仅支持初始化程序、实体成员和实体导航属性。错误。

我知道我已经能够使用 NHibernate 做到这一点。我什至可以用 EF 做到这一点吗?

【问题讨论】:

    标签: c# entity-framework criteria


    【解决方案1】:

    由于 EF 需要将您的 LINQ 语句转换为 SQL 语句, 你不能这样做。如果您有复杂的比较逻辑 overridden Equals() 方法,您必须在 LINQ 语句。

    public IQueryable<Foo> FoosEqualTo(IQueryable<Foo> allFoos, Foo target) {
    return from foo in allFoos
           where foo.Id == target.Id // or other comparison logic...
           select foo;
    }
    
    public Foo getFoo(Foo target) {
        return FoosEqualTo(DC.foos, target).FirstOrDefault();
    }
    

    【讨论】:

    • 我只能假设我的 get 中的 FirstOrDefault() 把它搞砸了......这可能是我毕竟不能走 NH 路,并且可能必须附加一个明确的 get-用于存储当前状态的私有设置属性...
    • 你可以尝试不进行 'x.state.equal' 对象比较,请告诉我结果。
    • 问题在于我不想将可以抽象出来的问题放到我的查询中! EF 似乎无法将方法解析为表达式!我不想做的事:.where(x => x.State.Id == OrderState.Accepted.Id) 我想做的事:.where(x => x.isInState(OrderState.Accepted));我正试图将我所有的担忧放在相关的地方。项目中还有其他类似的问题,这些查询会更大。
    猜你喜欢
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多