我有一个现有的服务器框架(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;
答案 0 :(得分:0)
这些只是样品。真实世界的解决方案会将数据存储在某些“商店”中,并在该商店上实现IQueryable。由于该实现通常是大量代码而与样本意图没有直接关系,因此未包含在样本中。
所以回答你的问题:
您需要在您使用的商店上实现IQueryable。如果这是一个DB,那么你需要一些ORM(如EF)来将数据库映射到CLR空间。 ORM通常还提供IQueryable实现。除了EF之外,还有NHibernate或LINQ to SQL。
您需要编写自定义提供程序代码(实现IDataServiceMetadataProvider,IDataServiceQueryProvider等接口),如示例所示,并从GetQueryRootForResourceSet返回商店的IQueryable(其中示例使用LINQ to Object的IQueryable实现)
请注意,自定义提供程序是很多工作。如果您可以使用像NHibernate或LINQ to SQL这样的ORM,那么使用反射提供程序会更快,并且可能仍然有用。