如何使用IQueryable方法返回额外数据?

时间:2014-02-26 20:21:22

标签: c# linq entity-framework breeze

我正在使用Entity Framework和Breeze。对于实体,我想提供一些与实体相关的数据。通过查询Entity表并加入其他表,可以最有效地获取此数据;此查询包括按子查询分组。

我试图通过将它作为[NotMapped]字段添加到实体来解决这些额外数据:

[NotMapped]
public string NotMappedField { get; set; }

那么我基本上想要替换这个webapi控制器方法

[HttpGet]
public IQueryable<MyObject> MyObjects()
{
    return _contextProvider.Context.MyObjects;
}

有这样的事情:

public IQueryable<MyObject> MyObjectsWithExtraData()
{
   var query = from o in _contextProvider.Context.MyObjects
               // big complex query
               select new MyObject
               {
                   FieldA = o.FieldA,
                   FieldB = o.FieldB,
                   // all fields
                   NotMappedField = x.ResultFromComplexJoin
               }
   return query;
}

这给了我一个错误:

  

无法在LINQ to Entities查询中构造实体或复杂类型“MyObject”。

我尝试过这几种方式,似乎从EF方面和Breeze方面都打击了我。我需要将其保留为返回类似IQueryable的东西,这样我就可以通过webapi从客户端进行过滤,因为在这里做类似ToList()的操作会因数据集大小而导致内存问题。

所以我的问题是 - 是否有一种最佳实践可以实现我的目标,或者任何人都可以提供解决方案?

更新

我发现你可以在你的实体旁边返回额外的数据,但仍然可以从Breeze查询实体:

public object MyObjectsWithExtraData()
{
    var query = from o in _contextProvider.Context.MyObjects
                // big complex query....
                select new
                {
                    theObject = MyObject,
                    NotMappedField = x.ResultFromComplexJoin
                };
    return query;
}

然后从客户端微风方面你可以做这样的事情:

var query = breeze.EntityQuery
           .from("MyObjectsWithExtraData")
           .where("theObject.FieldA", "Equals", 1)
           .expand("theObject.SomeNavigationalProperty")
           .orderBy("theObject.FieldB");

仍然不是我想要的,但它实际上很漂亮。

2 个答案:

答案 0 :(得分:0)

看一下EntityQuery.withParameters方法。

// client side
var q = EntityQuery.from("CustomersStartingWith")
        .withParameters({ companyName: "C" });


// server side
[HttpGet]
public IQueryable<Customer> CustomersStartingWith(string companyName) {
  var custs = ContextProvider.Context.Customers.Where(c => c.CompanyName.StartsWith(companyName));
  return custs;
}

您还可以将常规查询谓词的组合与这些自定义参数混合使用。

答案 1 :(得分:0)

LINQ to entity只能构造pur“Data Transfert Object”:只包含具有普通getter和setter且没有构造函数的公共属性的类。 请在此处查看我对类似问题的回答:https://stackoverflow.com/a/21174654/3187237

我指定了答案

无法在LINQ to Entities查询中实例化实体类。 如果要在查询中构造类似(或几乎相似),则必须定义其他类。

在您的情况下,您希望返回与MyObject几乎相似的对象。所以你必须定义一个类:

public class MyObjectExtended
{
    public string FieldA { get; set; }
    public string FieldB { get; set; }
    // ... all other MyObjetc fields
    public string ExtraFieldA { get; set; }
    public string ExtraFieldB { get; set; }
}

现在,您的服务可以返回IQueryable<MyObjectExtended>

public IQueryable<MyObjectExtended> MyObjectsWithExtraData() {
    var myQuery = from o in _contextProvider.Context.MyObjects
        // big complex query....
        select new MyObjectExtended {
           FieldA = o.FieldA,
           FieldB = o.FieldB,
           //... all fields ...
           ExtraFieldA = x.ResultFromComplexJoinA,
           ExtraFieldB = x.ResultFromComplexJoinB
    };
    return myQuery;
}

我希望这就是你要找的东西。