实体框架 4:如何将字符串转换为 .OrderBy(p => p.fieldname) 的对象?

发布于 2024-09-29 17:08:36 字数 1644 浏览 3 评论 0原文

现在这是一个棘手的问题,因为您不能这样做:

var a = myDB.Where(p => p.field == "filter").OrderBy("it." + fieldname);

您可以更改Where 来接受字符串,这允许您更改OrderBy 以接受字符串,但这不是问题。

如何将“productID、productName”等字符串转换为 OrderBy 表达式?如果我的想法是正确的,也许问题可能是“如何将规范模式转换为表达式委托?”

问题是我不知道他们想要什么表,因此我不知道主键。我使用泛型来表示表的类型。

public interface IRepository<E, C> where C : ObjectContext  // E is an Entity
{
  void Add(E entity);
  void Del(E entity);
  IList<E> Get(Expression<Func<E, bool>> filterLambda = null,   //Where clause
              Expression<Func<E, object>> orderbyLambda = null, //OrderBy
              int? page = null,                                 //Page to get
              int? pageSize = null,                             //Page Size
              Expression<Func<E, object>> selectLambda = null); //Populate Fields
  int Count(Expression<Func<E, bool>> filterLambda = null);
  bool SaveChanges();
}

我用来从数据上下文(数据容器?)中提取内容的实际语句是

this.GetEntity().Where(filterLambda)
                .OrderBy(orderbyLambda)
                .Skip(((int)page - 1) * (int)pageSize)
                .Take((int)pageSize)
                .Select(selectLambda).ToList();

需要 OrderBy() 来实现 .Skip().Take()。对于所有认为自己可以做到这一点的人来说,Linq to SQL 是正确的。但是,Linq to Entities 不支持它:

The method 'Skip' is only supported for sorted input in LINQ to Entities.
The method 'OrderBy' must be called before the method 'Skip'.

Now this is a trick question because you cannot do this:

var a = myDB.Where(p => p.field == "filter").OrderBy("it." + fieldname);

You could change the Where to accept a string, which allows you to change the OrderBy to accept a string, but that's not the question.

How can you turn a string like "productID, productName" in to an OrderBy expression? If I am correct in thinking, maybe the question could be "how to turn a Specification Pattern in to an Expression delegate?"

The problem is I don't know what table they want, and thus I don't know the primary key. I used generics to represent the type of table.

public interface IRepository<E, C> where C : ObjectContext  // E is an Entity
{
  void Add(E entity);
  void Del(E entity);
  IList<E> Get(Expression<Func<E, bool>> filterLambda = null,   //Where clause
              Expression<Func<E, object>> orderbyLambda = null, //OrderBy
              int? page = null,                                 //Page to get
              int? pageSize = null,                             //Page Size
              Expression<Func<E, object>> selectLambda = null); //Populate Fields
  int Count(Expression<Func<E, bool>> filterLambda = null);
  bool SaveChanges();
}

The actual statement I use to pull content from the data context (data container?) is

this.GetEntity().Where(filterLambda)
                .OrderBy(orderbyLambda)
                .Skip(((int)page - 1) * (int)pageSize)
                .Take((int)pageSize)
                .Select(selectLambda).ToList();

I need the OrderBy() to implement .Skip() and .Take(). For all those of you who think you can do this are correct for Linq to SQL. However, Linq to Entities does not support it:

The method 'Skip' is only supported for sorted input in LINQ to Entities.
The method 'OrderBy' must be called before the method 'Skip'.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾城泪 2024-10-06 17:08:36

您不必在单个语句中构建查询。由于直到最后执行 ToList 后才会执行查询,因此您可以使用条件来构建它。示例:(

var query = myDB.Where(p => p.field == "filter");

string sort = "productID, productName";

string[] sortItems = sort.Split(new string[] {", "}, StringSplitOptions.None);
switch (sortItems[0]) {
  case "productId": query = query.OrderBy(x => x.ProductId); break;
  case "productName": query = query.OrderBy(x => x.ProductName); break;
}
for (int i = 1; i < sortItems.Length; i++) {
  switch (sortItems[i]) {
    case "productId": query = query.ThenBy(x => x.ProductId); break;
    case "productName": query = query.ThenBy(x => x.ProductName); break;
  }
}
query = query.Skip(10).Take(10);

但是,当您添加排序时,查询对象的类型可能会发生变化(例如从 IEnumerableIOrderedEnumerable),因此您可能需要一些更多变量来存储不同阶段。)

You don't have to build the query in a single statement. As the query is not executed until you do the ToList at the end, you can use conditions to build it. Example:

var query = myDB.Where(p => p.field == "filter");

string sort = "productID, productName";

string[] sortItems = sort.Split(new string[] {", "}, StringSplitOptions.None);
switch (sortItems[0]) {
  case "productId": query = query.OrderBy(x => x.ProductId); break;
  case "productName": query = query.OrderBy(x => x.ProductName); break;
}
for (int i = 1; i < sortItems.Length; i++) {
  switch (sortItems[i]) {
    case "productId": query = query.ThenBy(x => x.ProductId); break;
    case "productName": query = query.ThenBy(x => x.ProductName); break;
  }
}
query = query.Skip(10).Take(10);

(However, the type of the query object may change when you add sorting (e.g. from IEnumerable<T> to IOrderedEnumerable<T>), so you might need some more variables to store the different stages.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文