C# 重构Linq代码并;LINQ to实体不识别该方法;
我试图重构LINQtoEntity查询以防止编写重复代码,但我无法避免“LINQtoEntities不识别方法”异常。原因是C# 重构Linq代码并;LINQ to实体不识别该方法;,c#,linq,linq-to-entities,entity-framework-5,C#,Linq,Linq To Entities,Entity Framework 5,我试图重构LINQtoEntity查询以防止编写重复代码,但我无法避免“LINQtoEntities不识别方法”异常。原因是IsUserActive方法 我提供下面的代码作为示例 public static bool IsUserActive(this User user) { return user.Orders.Any(c => c.Active && (c.TransactionType == TransactionType.Order || c.Transacti
IsUserActive
方法
我提供下面的代码作为示例
public static bool IsUserActive(this User user)
{
return user.Orders.Any(c => c.Active && (c.TransactionType == TransactionType.Order || c.TransactionType == TransactionType.Subscription));
}
public IQueryable<UserView> GetView()
{
return context.users.Select(p => new UserView
{
Id = p.Id,
Active =p.IsUserActive()
});
}
公共静态bool IsUserActive(此用户)
{
返回user.Orders.Any(c=>c.Active&(c.TransactionType==TransactionType.Order | | c.TransactionType==TransactionType.Subscription));
}
公共IQueryable GetView()
{
返回context.users.Select(p=>newuserview
{
Id=p.Id,
Active=p.IsUserActive()
});
}
在我的情况下,是否可以重构Linq代码以防止重复
- 我不能用IList代替IQueryable
- 我知道为什么会发生这种异常,不需要解释
public static Expression<Func<User, bool>> IsUserActive = user =>
user.Orders.Any(c => c.Active &&
(c.TransactionType == TransactionType.Order ||
c.TransactionType == TransactionType.Subscription));
public IQueryable<UserView> GetView()
{
return context.users.Select(p => new UserView
{
Id = p.Id,
Active = IsUserActive(p)
});
}
这有点棘手,但我们就是这样做的。您可以将多个iQueryTables组合为一个,如下所示
public static IQueryable<Order> ActiveOrdersQuery(this MyDBEntities db)
{
return db.orders.Where(
o=> o.Active &&
(o.TransactionType == TransactionType.Order ||
o.TransactionType == TransactionType.Subscription )));
}
public IQueryable<UserView> GetView()
{
var q = context.ActiveOrdersQuery();
return context.users.Select( x=> new UserView{
Id = x.Id,
Active = q.Any( o=> o.UserId == x.Id)
});
}
publicstaticiQueryableActiveOrderSquery(此MyDBEntities数据库)
{
返回db.orders.Where(
o=>o.激活&&
(o.TransactionType==TransactionType.Order||
o、 TransactionType==TransactionType.Subscription));
}
公共IQueryable GetView()
{
var q=context.ActiveOrdersQuery();
返回context.users.Select(x=>newuserview{
Id=x.Id,
Active=q.Any(o=>o.UserId==x.Id)
});
}
唯一的问题是必须显式比较外键。但这将产生完全相同的SQL,并将执行相同的操作
通过这种方式,您可以重构常见查询并在视图中使用它们。只需内联该方法即可。IsUserActive用于许多查询,我希望将其作为方法使用。在这个例子中,有很多情况下Linq代码在许多查询中重复,我没有找到重构查询的方法。我得到这个异常是因为Linq to Entity尝试将查询中的每个方法转换为sql。您是否尝试过常规方法而不是扩展方法?Linq可能只是变得混乱了我认为没有理解这里的概念IsUserActive不是Linq或dynmaic Linq扩展,所以您需要从Linq调用扩展方法,对吗?不要区分常规方法或扩展方法。原因是Linq无法将代码中的方法映射到SQL语句,但是它可以映射一个表达式,我得到编译错误。当前数据库中不存在名称“IsUserActive”context@Tomas如果新的
表达式
与扩展方法位于同一个静态类中,则需要在引用前加上所述静态类的名称。该类、方法和表达式都是静态方法,并且在IsUserActive上出现编译错误。当我在表达式方法VS show error“method,Delegate或Event is expected”上移动鼠标时。你的代码有问题。
public static IQueryable<Order> ActiveOrdersQuery(this MyDBEntities db)
{
return db.orders.Where(
o=> o.Active &&
(o.TransactionType == TransactionType.Order ||
o.TransactionType == TransactionType.Subscription )));
}
public IQueryable<UserView> GetView()
{
var q = context.ActiveOrdersQuery();
return context.users.Select( x=> new UserView{
Id = x.Id,
Active = q.Any( o=> o.UserId == x.Id)
});
}