ComponentOne OLAP for WinForms帮助文档
使用LINQ作为OLAP数据源

C1Olap可以采纳任何集合作为数据源。它并不受DataTable对象的限制。特别是,它还可以使用LINQ。

LINQ提供易用、高效、自由的模型用于查询数据。它使开发者可以很简单的在客户端应用中创建复杂查询而且不需要修改数据库,例如创建一个新的存储过程。这些查询可以转化为C1Olap数据源,所以最后用户同样可以创建它们自己的数据视图。

为了证明这一观点,创建一个新工程,然后添加一个C1OlapPage 控件到表单中。使用存储过程而不是像我们之前做的那样在designer中设置数据源属性。这一次我们将使用LINQ查询来加载数据,添加下述代码到表单构造函数中实现该效果:

public Form1()
{
  // designer
  InitializeComponent();
 
  // load all interesting tables into a DataSet
  var ds = new DataSet();
  foreach (string table in
    "Products,Categories,Employees," +
    "Customers,Orders,Order Details".Split(','))
  {
    string sql = string.Format("select * from [{0}]", table);
    var da = new OleDbDataAdapter(sql, GetConnectionString());
    da.Fill(ds, table);
  }
 
  // build LINQ query and use it as a data source
  // for the C1OlapPage control
  // …
}
// get standard nwind mdb connection string
static string GetConnectionString()
{
  string path = 
    Environment.GetFolderPath(Environment.SpecialFolder.Personal) + 
    @"\ComponentOne Samples\Common";
  string conn = @"provider=microsoft.jet.oledb.4.0;" +
    @"data source={0}\c1nwind.mdb;";
  return string.Format(conn, path);
}

上述代码从NorthWind数据库中加载了几张表。它假设位于”ComponentOne Samples”文件中的NorthWind数据库是可用的。文件位置由C1Olap安装时设置。如果你在其它地方放置了数据库,你将需要根据情况调整GetConnectionString方法。


接下来,我们将添加实际的LINQ查询。这是一个很长但是很简单的声明:

// build LINQ query
var q =
  from detail in ds.Tables["Order Details"].AsEnumerable()
  join product in ds.Tables["Products"].AsEnumerable()
    on detail.Field<int>("ProductID")
      equals product.Field<int>("ProductID")
  join category in ds.Tables["Categories"].AsEnumerable()
    on product.Field<int>("CategoryID")
      equals category.Field<int>("CategoryID")
  join order in ds.Tables["Orders"].AsEnumerable()
    on detail.Field<int>("OrderID")
      equals order.Field<int>("OrderID")
  join customer in ds.Tables["Customers"].AsEnumerable()
    on order.Field<string>("CustomerID") 
      equals customer.Field<string>("CustomerID")
  join employee in ds.Tables["Employees"].AsEnumerable()
    on order.Field<int>("EmployeeID")
      equals employee.Field<int>("EmployeeID")
  select new
  {
    Sales = (detail.Field<short>("Quantity") *
      (double)detail.Field<decimal>("UnitPrice")) * 
      (1 - (double)detail.Field<float>("Discount")),
    OrderDate = order.Field<DateTime>("OrderDate"),
    Product = product.Field<string>("ProductName"),
    Customer = customer.Field<string>("CompanyName"),
    Country = customer.Field<string>("Country"),
    Employee = employee.Field<string>("FirstName") + " " +
      employee.Field<string>("LastName"),
    Category = category.Field<string>("CategoryName")
  };
 
// use LINQ query as DataSource for the C1OlapPage control
c1OlapPage1.DataSource = q.ToList();

LINQ查询被分为两部分。第一部分使用几个join声明来连接我们从数据库中加载的表。每个表通过将它的主键添加到一个查询中可用字段的方式连接到查询中。我们从”Order Details”表开始,然后连接使用”ProductID”字段连接”Products”,使用”CategoryID”字段连接”Categories”。

一旦所有的表都完成连接,你可以创建一个select new声明来创建一个新的匿名类包含我们感兴趣的字段。需要注意的是,这些字段将直接映射到表中的字段,或者它们也许会参与计算。例如,”Sales”字段将参与基于数量,单位价格以及折扣内容的计算。

一旦LINQ查询准备就绪,你可以使用LINQ的ToList方法将其转化成一个列表,然后将结果赋值给DataSource属性。ToList方法是必须的,因为只有它才能启动查询。如果你想简单的将查询赋值给任何控件的DataSource属性,你将会得到一个语法错误提示。

如果你现在运行项目,你将看到它和上一个项目类似,虽然这次我们使用存储过程作为数据源。使用LINQ的优点在于查询可以生成到应用中。你可以在不需要数据库管理员帮助的情况下修改它。

 

 


产品网站:http://www.gcpowertools.com.cn 咨询热线:4006576008 ©2015 西安葡萄城