【问题标题】:oData with custom providerso具有自定义提供程序的数据
【发布时间】:2013-03-05 20:56:47
【问题描述】:

我有一个现有的服务器框架(WCF 服务),我需要升级到“oData”格式。 我从“oData”站点下载了一些 oData 示例: http://www.odata.org/ecosystem

我想避免使用“实体框架”,因为它需要重写我的大量代码,所以我选择了“自定义提供程序”解决方案。在我看到的所有例子中,有些东西让我觉得很奇怪:

WCF 方法的调用调用“CreateDataSource()”方法(附加代码),该方法为每次调用从头开始初始化整个数据模型。在这个演示版本中,重新加载 6 个业务实体实例,然后过滤它们并不是什么大问题,但在现实生活中:我会有数百个表,每个表包含 1000-1000000 行。

我应该如何避免每次都将整个数据库加载到内存中?我可能遗漏了一些东西,否则这项技术将没有用处。

 protected override DSPContext CreateDataSource()
    {
        DSPContext context = new DSPContext();

        ResourceSet productsSet, categoriesSet;
        this.Metadata.TryResolveResourceSet("Products", out productsSet);
        this.Metadata.TryResolveResourceSet("Categories", out categoriesSet);
        IList<DSPResource> products = context.GetResourceSetEntities(productsSet.Name);
        IList<DSPResource> categories = context.GetResourceSetEntities(categoriesSet.Name);

        var categoryFood = new DSPResource(categoriesSet.ResourceType);
        categoryFood.SetValue("ID", 0);
        categoryFood.SetValue("Name", "Food");
        categoryFood.SetValue("Products", new List<DSPResource>());
        categories.Add(categoryFood);

        var categoryBeverages = new DSPResource(categoriesSet.ResourceType);
        categoryBeverages.SetValue("ID", 1);
        categoryBeverages.SetValue("Name", "Beverages");
        categoryBeverages.SetValue("Products", new List<DSPResource>());
        categories.Add(categoryBeverages);

        var categoryElectronics = new DSPResource(categoriesSet.ResourceType);
        categoryElectronics.SetValue("ID", 2);
        categoryElectronics.SetValue("Name", "Electronics");
        categoryElectronics.SetValue("Products", new List<DSPResource>());
        categories.Add(categoryElectronics);

        var productBread = new DSPResource(productsSet.ResourceType);
        productBread.SetValue("ID", 0);
        productBread.SetValue("Name", "Bread");
        productBread.SetValue("Description", "Whole grain bread");
        productBread.SetValue("ReleaseDate", new DateTime(1992, 1, 1));
        productBread.SetValue("DiscontinueDate", null);
        productBread.SetValue("Rating", 4);
        productBread.SetValue("Category", categoryFood);
        productBread.SetValue("BackupCategoryID", 2);
        productBread.SetValue("RelatedProductID", 1);
        products.Add(productBread);

        var productMilk = new DSPResource(productsSet.ResourceType);
        productMilk.SetValue("ID", 1);
        productMilk.SetValue("Name", "Milk");
        productMilk.SetValue("Description", "Low fat milk");
        productMilk.SetValue("ReleaseDate", new DateTime(1995, 10, 21));
        productMilk.SetValue("DiscontinueDate", null);
        productMilk.SetValue("Rating", 3);
        productMilk.SetValue("Category", categoryBeverages);
        productMilk.SetValue("BackupCategoryID", 2);
        productMilk.SetValue("RelatedProductID", 2);
        products.Add(productMilk);

        var productWine = new DSPResource(productsSet.ResourceType);
        productWine.SetValue("ID", 2);
        productWine.SetValue("Name", "Wine");
        productWine.SetValue("Description", "Red wine, year 2003");
        productWine.SetValue("ReleaseDate", new DateTime(2003, 11, 24));
        productWine.SetValue("DiscontinueDate", new DateTime(2008, 3, 1));
        productWine.SetValue("Rating", 5);
        productWine.SetValue("Category", categoryBeverages);
        productWine.SetValue("BackupCategoryID", 4);
        productWine.SetValue("RelatedProductID", 3);
        products.Add(productWine);

        ((List<DSPResource>)categoryFood.GetValue("Products")).Add(productBread);
        ((List<DSPResource>)categoryBeverages.GetValue("Products")).Add(productMilk);
        ((List<DSPResource>)categoryBeverages.GetValue("Products")).Add(productWine);

        return context;

【问题讨论】:

    标签: wcf-data-services odata


    【解决方案1】:

    这些只是示例。现实世界的解决方案会将数据存储在某个“存储”中,并在该存储上实现 IQueryable。由于该实现通常包含大量代码,并且与示例意图没有直接关系,因此未包含在示例中。

    所以回答你的问题:

    • 您需要在您使用的商店上实现 IQueryable。如果这是一个数据库,那么您需要一些 ORM(如 EF)将数据库映射到 CLR 空间。该 ORM 通常还提供 IQueryable 实现。除了 EF,还有 NHibernate 或 LINQ to SQL。

    • 您需要编写示例中所示的自定义提供程序代码(实现 IDataServiceMetadataProvider、IDataServiceQueryProvider 等接口),并从 GetQueryRootForResourceSet 中返回存储的 IQueryable(示例使用 LINQ to Object 的 IQueryable 实现) .

    请注意,自定义提供程序需要做很多工作。如果您可以使用 NHibernate 或 LINQ to SQL 之类的 ORM,则使用反射提供程序会更快,并且可能仍然有效。

    【讨论】:

    • odata.org/ecosystem#samplecode - 查找 OData Provider Toolkit,它包含自定义提供程序的示例。但请注意,它们都不包含示例 IQueryable,它们都使用 LINQ to Objects。
    猜你喜欢
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多