Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 如何在OData服务下使用字典或哈希表实现LINQ查询性能_Performance_Linq_Wcf Data Services_Odata - Fatal编程技术网

Performance 如何在OData服务下使用字典或哈希表实现LINQ查询性能

Performance 如何在OData服务下使用字典或哈希表实现LINQ查询性能,performance,linq,wcf-data-services,odata,Performance,Linq,Wcf Data Services,Odata,我对OData很陌生(昨天才开始),所以如果这个问题太愚蠢,请原谅:-) 我构建了一个测试项目,作为将当前web服务迁移到OData的概念证明。对于这个测试项目,我使用反射提供者通过OData公开POCO类。这些POCO类来自内存缓存。以下是迄今为止的代码: public class DataSource { public IQueryable<Category> CategoryList { get { Lis

我对OData很陌生(昨天才开始),所以如果这个问题太愚蠢,请原谅:-)

我构建了一个测试项目,作为将当前web服务迁移到OData的概念证明。对于这个测试项目,我使用反射提供者通过OData公开POCO类。这些POCO类来自内存缓存。以下是迄今为止的代码:

public class DataSource
{
    public IQueryable<Category> CategoryList
    {
        get
        {
            List<Category> categoryList = GetCategoryListFromCache();
            return categoryList.AsQueryable();
        }
    }
    // below method is only required to allow navigation
    // from Category to Product via OData urls
    // eg: OData.svc/CategoryList(1)/ProductList(2) and so on
    public IQueryable<Category> ProductList
    {
        get
        {
            return null;
        }
    }
}

[DataServiceKeyAttribute("CategoryId")]
public class Category
{
    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
    public List<Product> ProductList { get; set; }
}

[DataServiceKeyAttribute("ProductId")]
public class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
}
公共类数据源
{
公共可查询分类列表
{
得到
{
List categoryList=GetCategoryListFromCache();
返回categoryList.AsQueryable();
}
}
//下面的方法仅用于允许导航
//通过OData URL从类别到产品
//例如:OData.svc/CategoryList(1)/ProductList(2)等等
公共可查询产品列表
{
得到
{
返回null;
}
}
}
[DataServiceKeyAttribute(“CategoryId”)]
公共类类别
{
public int CategoryId{get;set;}
公共字符串CategoryName{get;set;}
公共列表ProductList{get;set;}
}
[DataServiceKeyAttribute(“ProductId”)]
公共类产品
{
public int ProductId{get;set;}
公共字符串ProductName{get;set;}
}
据我所知,OData将在后台使用LINQ来查询这些内存中的对象,即:如果有人导航到OData.svc/CategoryList(1)/ProductList(2)等,则在本例中为:List

但问题是:在现实世界中,我看到缓存中有超过1800万条记录,代表24个不同的实体

当前的生产web服务很好地利用了.NET字典和哈希表集合,以确保快速查找并避免大量循环。因此,要在CategoryID为1的类别下找到ProductID为2的产品,当前的web服务只需进行两次查找,即:第一次查找类别,第二次查找类别内的产品。像树一样的东西

我想知道我如何能够遵循与OData类似的体系结构,让OData和LINQ使用字典或哈希表来定位记录,而不是在通用列表上循环

是否可以使用反射提供程序,或者我别无选择,只能为OData编写自定义提供程序


提前感谢。

您将需要处理表达式树,因此您至少需要在基础LINQ to对象上实现部分IQueryable。为此,您不需要完整的自定义提供程序,只需从上下文类的propties返回IQueryable即可。 在IQueryable中,您必须识别“key”属性(.Where(p=>p.ProductID=2))上的过滤器,并将其转换为字典/哈希表查找。然后可以使用LINQ to对象来处理查询的其余部分。
但是,如果客户机发出一个带有过滤器的查询,而该过滤器不涉及key属性,那么它将最终执行完整扫描。尽管如此,如果您选择,您的自定义IQueryable可能会检测到这一点并导致查询失败。

太好了。。。在真实的odata世界中,你遇到过这样的例子吗?到目前为止,我还没有在谷歌上找到过这样的公开样本。看看这个。它本身描述了您可能遇到的表达式树。还有一个链接指向Matt关于LINQ提供商的博客系列。