Step-by-Step: 在Visual Studio 2010上安装SQL Server Management Studio 2008 Express

[原文发表地址] Step-by-Step: Installing SQL Server Management Studio 2008
Express after Visual Studio 2010

[原文发表时间] 18 Feb 2011 8:14 AM

安装完Visual
Studio后,我经常要做的第一件事是安装SQL Server Management Studio (SSMS)。Visual Studio 2010 在你的机器上安装了 SQL
Server 2008 Express,但是不包括SSMS。尽管可以用Visual Studio来创建/连接/设计数据库,但是我还是喜欢使用SSMS因为它有更高级的管理功能。我想起了SQL Server 2005的SSMS是一个小的安装,不幸的是它们把太多不必要的东西放入SSMS
2008的安装程序中,我经常疑惑,不知道按哪个按钮来使它做我指定的事。因此,我写这篇博客有两方面的原因1)我记得步骤 2)您可以少些疑惑:-)(顺便提下,有人告诉我说SQL团队正在研究将来把这个安装程序做得更简单。万岁!)

你首先要做的是确保你有合适的SSMS版本。如果你安装了Visual
Studio 2010,那么你需要安装2008版本的(而不是R2)。

第一步:下载 Microsoft® SQL Server® 2008 Management Studio Express ,根据你的机器操作系统位数安装SQLManagementStudio_x64_ENU.exe
或者SQLManagementStudio_x86_ENU.exe。我运行的是Windows
7-64位的,因此我会详细讲解适合这个OS的步骤。
第二步:确保你是以管理员身份登录的,然后右击你已经下载的exe,选择“Run as Administrator”。如果你使用的是Windows 7,那么你就会有一个兼容性警告。点过它继续安装,继续安装。稍后你就需要使用SQL
2008 服务包 2

第三步:现在你就应该可以看到“SQL
Server 安装中心” 的窗口。它看起来确实是有些吓人。选择“安装”键。

第四步:选择“新的SQL Server 独立安装或 向已有的安装中添加功能”。接下来它将会进行一个规则检查。确保没有错误后点击OK。

第五步:接下来的步骤很让人误解。启动支持文件窗口看起来很像是在执行任务,阻塞在了“Gathering user settings.”。实际上,它是在等你点击安装按钮!

第六步:另一个规则检查检查。这次你可能会以Windows防火墙警告结束。如果想能够远程接入到SQL
Server,,你将要配置后面的防火墙 。由于我只将SQL Server Express用于本机上的开发,我不必担心它。点击 下一步 。

第七步:这一步我经常搞得乱七八糟 的 ,因为它一点也不是能考直觉获得的 。在安装类型窗口中,你要在“执行SQL Server 2008的一个新安装” 或者“向SQL Server 2008的一个已有的实例添加 功能” 做一个选择。你需要选择新安装而不是添加功能。我知道,我知道,总归不可思议。你会觉得你只想添加SSMS,这应该选择向已有的实例中添加功能—我的意思是我不想要一个新的实例,只是只是个工具而已。唉,点击下一步。

第八步: 接下来你进入了产品密钥窗口。显然地,对SQL Server Express你不必需要产品密钥,因为它是免费的,所以只要点击下一步。

第九步:接受序列号条款,点击下一步。

第十步:好了,现在对于那个窗口,我们一直都在等待—功能选项。核对“Management Tools – Basic”,点击下一步。

第十一步:核对你的磁盘空间要求,点击下一步。

第十二步:选择发送应用和错误报告来帮助Microsoft提高SQL Server的功能和服务。点击下一步。

第十三步:另一个快速的规则检查。点击下一步。

第十四步:现在看起来我们已经准备好安装了。点击安装按钮。

安装将开始并用五分钟来完成安装。
第十五步:安装完成后,再次点击下一步按钮。


第十六步:完成! 点击关闭按钮,你应该全部设置。

第十七步:激活SQL Server Management Studio!现在你应该会看到它在Microsoft SQL Server 2008下的程序中。为了能够使用所有的功能, 你要确保是以管理员身份登录。

不要忘记在某些情况下安装最新的SQL
Server 2008服务包
。我希望这可以帮助那些只安装了Visual Studio 2010但也想安装SQL Server Management Studio的人们。我知道当我需要这么做时也会参考我自己的这篇博客:-)
用得开心!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Duet Enterprise与Excel 2010

[原文发表地址] Duet Enterprise and Excel 2010

[原文发表时间] 2/3/2011 7:08 AM

下面是一个示例的分步说明。该示例基于集成在Excel2010内的Duet Enterprise列表。示例的目的是在Excel2010电子表格中显示Customer列表。

准备步骤

要在VSTO Excel应用程序中通过外部内容类型(External Content Type)使用外部列表(External List),你需要进行以下操作:

· 根据外部内容类型创建一个外部列表;

clip_image002

clip_image004

clip_image006

clip_image008

Excel VSTO 应用程序

1. 用Visual Studio 2010创建一个VSTO Workbook项目:

clip_image010

2. 在项目文件夹Helpers内创建一个名为SPHelper的辅助类:

clip_image012

3. 往项目内添加一个与Common文件夹下CommonTypes.cd类内的Customer结构对应的类型:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace DuetExcelWorkbook.Common

{

public struct CustomerType

{

public string FirstLineName;

public string CountryCode;

public string AddressregionCode;

public string AddresscityName;

}

}

4. 添加Client OM程序集:

– C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\

在项目内引用以下两个程序集:

o Microsoft.SharePoint.Client.dll

o Microsoft.SharePoint.Client.Runtime.dll

在Common下创建名为SPHelpers.cs的类:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.SharePoint.Client;

using System.Linq.Expressions;

using System.Xml;

namespace DuetExcelWorkbook.Helpers

{

public static class SPHelper

{

public static List<CustomerType> GetCustomerList(string TargetSiteUrl, string TargetListName)

{

List<CustomerType> CustomerList = new List<CustomerType>();

try

{

ClientContext clientContext = new ClientContext(TargetSiteUrl);

List externalList = clientContext.Web.Lists.GetByTitle(

TargetListName);

// To properly construct the CamlQuery and

// ClientContext.LoadQuery,

// we need some View data of the Virtual List.

// In particular, the View will give us the CamlQuery

// Method and Fields.

clientContext.Load(

externalList.Views,

viewCollection => viewCollection.Include(

view => view.ViewFields,

view => view.HtmlSchemaXml));

// This tells us how many list items we can retrieve.

clientContext.Load(clientContext.Site,

s => s.MaxItemsPerThrottledOperation);

clientContext.ExecuteQuery();

// Let’s just pick the first View.

View targetView = externalList.Views[0];

string method = ReadMethodFromViewXml(

targetView.HtmlSchemaXml);

ViewFieldCollection viewFields = targetView.ViewFields;

CamlQuery vlQuery = CreateCamlQuery(

clientContext.Site.MaxItemsPerThrottledOperation,

method,

viewFields);

Expression<Func<ListItem, object>>[] listItemExpressions =

CreateListItemLoadExpressions(viewFields);

ListItemCollection listItemCollection =

externalList.GetItems(vlQuery);

// Note: Due to limitation, you currently cannot use

// ClientContext.Load.

// (you’ll get InvalidQueryExpressionException)

IEnumerable<ListItem> resultData = clientContext.LoadQuery(

listItemCollection.Include(listItemExpressions));

clientContext.ExecuteQuery();

foreach (ListItem li in resultData)

{

// Now you can use the ListItem data!

CustomerType customer = new CustomerType();

customer.FirstLineName = li["FirstLineName"].ToString();

//customer.AddresscityName = li["AddresscityName"].ToString();

//customer.AddressregionCode = li["AddressregionCode"].ToString();

customer.CountryCode = li["CountryCode"].ToString();

CustomerList.Add(customer);

Console.WriteLine("First Name: {0} Country : {1} \n", li["FirstLineName"].ToString(), li["CountryCode"].ToString());

// Note: In the CamlQuery, we specified RowLimit of

// MaxItemsPerThrottledOperation.

// You may want to check whether there are other rows

// not yet retrieved.

}

}

catch (Exception ex)

{

throw ex;

}

return CustomerList;

}

/// <summary>

/// Parses the viewXml and returns the Method value.

/// </summary>

private static string ReadMethodFromViewXml(string viewXml)

{

XmlReaderSettings readerSettings = new XmlReaderSettings();

readerSettings.ConformanceLevel = ConformanceLevel.Fragment;

XmlReader xmlReader = XmlReader.Create(

new StringReader(viewXml), readerSettings);

while (xmlReader.Read())

{

switch (xmlReader.NodeType)

{

case XmlNodeType.Element:

if (xmlReader.Name == "Method")

{

while (xmlReader.MoveToNextAttribute())

{

if (xmlReader.Name == "Name")

{

return xmlReader.Value;

}

}

}

break;

}

}

throw new Exception("Unable to find Method in View XML");

}

/// <summary>

/// Creates a CamlQuery based on the inputs.

/// </summary>

private static CamlQuery CreateCamlQuery(

uint rowLimit, string method, ViewFieldCollection viewFields)

{

CamlQuery query = new CamlQuery();

XmlWriterSettings xmlSettings = new XmlWriterSettings();

xmlSettings.OmitXmlDeclaration = true;

StringBuilder stringBuilder = new StringBuilder();

XmlWriter writer = XmlWriter.Create(

stringBuilder, xmlSettings);

writer.WriteStartElement("View");

// Specifies we want all items, regardless of folder level.

writer.WriteAttributeString("Scope", "RecursiveAll");

writer.WriteStartElement("Method");

writer.WriteAttributeString("Name", method);

writer.WriteEndElement(); // Method

if (viewFields.Count > 0)

{

writer.WriteStartElement("ViewFields");

foreach (string viewField in viewFields)

{

if (!string.IsNullOrEmpty(viewField))

{

writer.WriteStartElement("FieldRef");

writer.WriteAttributeString("Name", viewField);

writer.WriteEndElement(); // FieldRef

}

}

writer.WriteEndElement(); // ViewFields

}

writer.WriteElementString(

"RowLimit", rowLimit.ToString(CultureInfo.InvariantCulture));

writer.WriteEndElement(); // View

writer.Close();

query.ViewXml = stringBuilder.ToString();

return query;

}

/// <summary>

/// Returns an array of Expression used in

/// ClientContext.LoadQuery to retrieve

/// the specified field data from a ListItem.

/// </summary>

private static Expression<Func<ListItem, object>>[]

CreateListItemLoadExpressions(

ViewFieldCollection viewFields)

{

List<Expression<Func<ListItem, object>>> expressions =

new List<Expression<Func<ListItem, object>>>();

foreach (string viewFieldEntry in viewFields)

{

// Note: While this may look unimportant,

// and something we can skip, in actuality,

// we need this step. The expression should

// be built with local variable.

string fieldInternalName = viewFieldEntry;

Expression<Func<ListItem, object>>

retrieveFieldDataExpression =

listItem => listItem[fieldInternalName];

expressions.Add(retrieveFieldDataExpression);

}

return expressions.ToArray();

}

}

5. 现在我们将编码实现用户界面,其中部分代码将调用Client OM类。

往项目内添加一个Ribbon

clip_image014

更改下面这些Ribbon的属性:

Label: Duet Enterprise

Name: tabDuet

往Ribbon上添加一个按钮,更改其属性如下:

ControlSize: RibbonControlSizeLarge
Label: Customers
OfficeImageId: SlideMasterChartPlacehoderInsert

6. 往buttonCustomers_Click()函数内添加如下代码:

private void buttonCustomers_Click(object sender, RibbonControlEventArgs e)

{

List<CustomerType> result = new List<CustomerType>();

try

{

result = SPHelper.GetCustomerList("http://litware", "SAPCustomers");

//string[] Names = new string[];

//string[] Countries;

List<string> Names = new List<string>();

List<string> Countries = new List<string>();

int counter = 0;

// Fill the collections

foreach (var item in result)

{

// Add the customers in the ListView

Names.Add(item.FirstLineName);

Countries.Add(item.CountryCode);

counter++;

}

// Create a data table with two columns.

System.Data.DataTable table = new DataTable();

DataColumn column1 = new DataColumn("Name", typeof(string));

DataColumn column2 = new DataColumn("Country", typeof(string));

table.Columns.Add(column1);

table.Columns.Add(column2);

// Add the four rows of data to the table.

DataRow row;

for (int i = 0; i < counter; i++)

{

row = table.NewRow();

row["Name"] = Names[i];

row["Country"] = Countries[i];

table.Rows.Add(row);

}

Microsoft.Office.Tools.Excel.ListObject list1 =

Globals.Sheet1.Controls.AddListObject(Globals.Sheet1.Range["A1", "B4"], "list1");

// Bind the list object to the table.

list1.SetDataBinding(table);

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

throw;

}

}

7. 运行Visual Studio

注意:请确保Visual Studio以正确的用户身份运行。用户必须有读取Customers列表的权限。

点击Duet Enterprise Ribbon,然后点击 Customers按钮,你就会看到customers列表被加到Microsoft Excel中去了:

clip_image016

在Insert操作中刷新主键识别列

[原文作者]:John Chen

[原文链接]:Refresh the Primary Key Identity Column during Insert Operation

        如果你在数据表中定义了主键标识列,当你在这个表中插入新行时,数据库引擎会自动设置它的值。这个标识值是由列的标识种子和标识递增的属性决定的。

        在客户端应用中,你可以在对应的ADO.NET 数据表中插入新行(数据表可以被看做数据库在缓存中的数据表,在本文中我会用数据表举例说明)。

        在这篇文章中,我将描述一下利用VS 数据库工具如何检索ADO.NET应用程序中的标识值。用Windows Forms Application DataSet举例,数据库服务器是SQL Server.

        首先在VS(2005或者之后的版本)服务器资源管理器中建立和一个SQL Server数据库的连接。创建一个名称为MyCustomer的表,包含三列:CustId, Name和Company. CustId被定义为主键和标识列。标识种子和标识递增为缺省值1,如下表:

clip_image001

图1 数据库中定义的MyCustomer 表

        然后我通过数据源配置向导创建DataSet,或者可以增加一个DataSet,然后将MyCustomer从服务器资源管理器拖到DataSet设计器上面。打开DataSet,学则CustId列,你将会看到它有以下的属性:AutoIncrement=True, AutoIncrementSeed = -1 , AutoIncrementStep = -1 (图2)。这些属性会被ADO.NET用来自动生成CustId新增行的占位符。

clip_image002

图2 数据表中CustId的属性

        数据库中属性AutoIncrement对应于Identity,属性AutoIncrementSeed和AutoIncrementStep 分别对应于Identity Seed和Identity Increment。你可能对AutoIncrementSeed和AutoIncrementStep都设置为-1感到奇怪。原因是这样可以保证ADO.NET生成的占位符的值不会和数据库中已有的值冲突,另外一个好处是它看起来不真实,所以用户会知道它仅仅是一个临时的占位符。

现在如果你点击MyCustomerTableAdapter header并且显示出Insert命令,你会看到:

INSERT INTO [MyCustomer] ([Name], [Company]) VALUES (@Name, @Company);

SELECT CustId, Name, Company FROM MyCustomer WHERE (CustId = SCOPE_IDENTITY())

这些命令行包括了两个语句,第二个语句在Insert操作提交后用来检索主键值。注意SCOPE_IDENTITY函数的运用,在MSDN中获取详细信息。

第二个插入语句的自动生成是由TableAdapter Configuration Wizard(表3)中的“refresh data table option”控制的。

clip_image003

3 TableAdapter Configuration Wizard中刷新数据表的高级选项

        现在让我们来体验一下在运行时应用refresh data table 功能。打开窗口,显示出Data Sources Window,将表MyCustomer拖到窗口上得到如下的布局(图4):

clip_image004

图4 设计时:将表MyCustomer从DataSourcesWindow拖到窗口上

按下F5运行,点击Add New(the+sign)按钮增加新的行,注意我会得到的CustId 列的值分别为-1,-2, -3等。

clip_image005

图5 CustForm运行时(提交之前)

现在我点击Save(the disk sign)按钮,CustId的值更新为9,10,11。哦!我本来期望的是2,3,4;

可能是有人在我操作之前增加了新的行。在这里你可以看到-1,-2,-3的优势,它们清楚的表明了没有提交的值。

clip_image006

图6 CustForm运行时(提交之后)

        现在如果你使用MS Access 数据库或者SQL CE,你将会看到以上的步骤不会像期望的那样工作。当你点击Save,主键-1,-2,-3是保持不变的。如果你检查TableAdapter Configuration Wizard, Refresh the data table 选项是不可用的。如果你检查生成的Insert命令,只有一条语句。原因是MS Access 数据库和SQL CE不支持SQL 批处理语句,因此不能使用SCOPE_IDENTITY()函数。Refresh the data table选项对于这些数据库是无效的。

        有一个好消息是找到一个解决办法,通过Adapter.RowUpdated事件重新设置主键标识值。请看Beth Massi的博客Using TableAdapters to Insert Related Data into an MS Access Database. Beth Massi 也会写一篇关于SQL CE的文章。

        总之,SQL server 或其它任何支持批处理的数据库通过使用SCOPE_IDENTITY()函数都可以可靠地检索标识值,Visual Studio Data Tool提供了自动生成Insert命令通过默认打开“Refresh the data table”选项。对于不支持批处理SQL 语句的数据库来说,通过RowUpdated事件重新设置主键值是好的解决方法。

如何绑定数据集到WPF设计器

[原文作者]:Yao Hai

[原文链接]:WPF Data Binding: How to Bind DataSet to WPF Designer

        在我们前面的章节中,对于WPF数据绑定方案,我们常常使用的是实体数据模型作为ORM(对象关系映射)层。

        同时,自从数据集的广泛使用, 我们也提供对数据集作为数据源在数据绑定方法。下面的例子是使用C#一步一步实现的,这个例子是基于Visual Studio 2010 Beta2 版本。

绑定数据集到WPF 设计器

        1. 打开Visual Studio 从主菜单: 文件->新建项目,选择WPF 应用程序 创建一个新的C#应用程序。这里我们就使用项   目默认的名称: WpfApplication1。

        2. 从主菜单: 数据-> 增加新的数据源…->数据库->数据集触发数据源向导。

        3. 根据这个向导连接到数据库Northwind,然后选择表Customers,Orders。完成这一步以后,下面的截图就是数据库显示的状态。

image 

        4. 从主菜单: 数据->显示数据源显示数据源工具窗口,确保MainWindow.xaml是个活动的窗口。

        5. 切换到数据源工具窗口,你可以单击”Customers” 节点和下拉菜单。在context菜单中, 选择”自定义…”, 一个”自定义控制绑定”的对话框弹出, 在组合框中选择”[List]”作为数据类型。

image

        6. 绑定”Customers”表到组合框控件,经过上面的步骤后,下面的是拖放前的快照。从这个图标中,你可以看到”Customers” 已经绑定到组合框。

image

        7. 把”Customers”表拖到左上角,然后把”Customers.Orders”拖到WPF设计器的中间。布局如下面所示:

clip_image004[4]

        这些步骤以后, 一个简单的数据集 Master-Detail应用程序已经创建。你可以按下”Ctrl + F5”运行这个程序去查看这个数据。

说明:

        在第五步中,有2部分代码生成: 一部分是xaml标记代码和C#的后台代码。这些代码是用着示范。我解释一下它们之间的对应关系以至于提供一个指导方案来修改这些代码。

        这些xaml代码,除了标记控制/数据绑定外,它们都相同的使用了EDM作为PRM层。它也生成资源块。

<Window.Resources>

        <my:NorthwindDataSet x:Key="NorthwindDataSet" />

        <CollectionViewSource x:Key="customersViewSource" Source="{Binding Path=Customers, Source={StaticResource NorthwindDataSet}}" />

        <CollectionViewSource x:Key="customersOrdersViewSource" Source="{Binding Path=FK_Orders_Customers, Source={StaticResource customersViewSource}}" />

</Window.Resources>

        第一行定义了一个NorthwindDataSet的实例,它具体到数据集。所以当一个窗口初始化时,就有一个数据集实例创建。第二和第三行代码是利用CollectionViewSource做master-details data-binding。

下面的是C#代码:

private void Window_Loaded(object sender, RoutedEventArgs e)

{

WpfApplication1.NorthwindDataSet NorthwindDataSet = ((WpfApplication1.NorthwindDataSet)(this.FindResource("NorthwindDataSet")));

// Load data into the table Customers. You can modify this code as needed.

WpfApplication1.NorthwindDataSetTableAdapters.CustomersTableAdapter northwindDataSetCustomersTableAdapter = new WpfApplication1.NorthwindDataSetTableAdapters.CustomersTableAdapter();

northwindDataSetCustomersTableAdapter.Fill(NorthwindDataSet.Customers);

System.Windows.Data.CollectionViewSource customersViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("customersViewSource")));

customersViewSource.View.MoveCurrentToFirst();

// Load data into the table Orders. You can modify this code as needed.

WpfApplication1.NorthwindDataSetTableAdapters.OrdersTableAdapter northwindDataSetOrdersTableAdapter = new WpfApplication1.NorthwindDataSetTableAdapters.OrdersTableAdapter();

northwindDataSetOrdersTableAdapter.Fill(NorthwindDataSet.Orders);

System.Windows.Data.CollectionViewSource customersOrdersViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("customersOrdersViewSource")));

customersOrdersViewSource.View.MoveCurrentToFirst();

}

        第一行,从WPF设计资源字典得到一个数据集实例。第二行是导入Customers数据到表中。当然你也可以用你喜欢的数据集实例替换它。第三和第四行是初始化CollectionViewSource。第5到7行,对于Customers.Orders表,和第二、第四行相似。

        你可能注意到当应用程序开始运行时数据开始导入。如果你想根据需要导入,你可以把这些代码放到事件中比如按钮的单击事件或者其他的一些事件。

在Visual Studio 2010使用数据服务进行映射

 

[原文作者]:Beth Massi

[原文链接]:Sharing the goodness that is VB

 

    从Visual Studio 2008 Service Pack 1开始,您可以通过创建ADO.NET数据服务很容易的接触到REST风格的Web服务数据模型。所以如果您正想着搭建一个CRUD的远程数据访问层,那么这可能是你正在使用或者正在寻求的一门技术,我写了很多关于关于在VS2008的数据服务,我最喜欢的是:

针对Visual Studio 2010 和 the .NET Framework 4,我们已经将这门技术的名称改为WCF数据服务, 并且增加了一些新的特征, 其中之一就是我在这想谈的查询映射, 但是首先……

什么是查询规划?

    如果您一直在LINQ查询那么你可能已经写过很多的映射,一个映射,可以用来限制返回的成员集数量的属性,或者用来执行属性的转换,可以有选择的做到的这些。例如:我是有一个负有12个属性特征的的客户名单,但我只想在我的结果集合里显示他们夫妇的名单。我这样写:

Dim result = From c In customerList Select c.CustomerID, c.ContactName

    这将产生一个只有CustomerID和ContactName属性的匿名列表,我们说,这个查询将Customer的属性映射到匿名的类型中。你也可以将自己的结果映射到已经的类型中。例如,假设我有一个拥有两个属性特这的MyCustomer类:

Class MyCustomer

Property CustomerID As Integer

Property ContactName As String

End Class

    我也这样写这个查询来替代,以便它可以将结果映射到MyCustomer这个类的对象集中:

Dim result = From c In customerList

Select New MyCustomer With

{.CustomerID = c.CustomerID,

.ContactName = c.ContactName}

数据服务支持查询映射

    当你写一个针对数据服务的查询它将转化为一个HTTP GET调用,你可以使用LINQ数据查询服务来执行约束(Where)、排序(Order by)以及其他的一些基本表达,尽管不是支持所有的LINQ语法。遗憾的是在Visual Studio 2008 SP1中你不能使用一个查询映射(Select)到数据服务,你会得到一个NotSupportedException的错误信息,这意味着你所有在数据服务背后定义的实体模块的属性都被返回了。如果你有带有许多属性的实体或者属性中含有超负荷的属性,比如图片,或者其他一些二进制的数据,这或许是一个障碍。无论你用不用它们,所有这些都要被设置最低限。让我来告诉你我的意思:

我有一个的Northwind数据库,通过它来揭露.NET 3.5 SP1的数据服务。就像我们在以前的帖子建立实体框架模型。它具有分类和产品的实体。该类别的实体有一个Picture属性,但我不需要在我的客户端应用程序使用它。我已经添加到客户服务的引用,你会认为我们以下内容可以这么写吗:

Dim svc As New NorthwindService.NorthwindEntities(New Uri("http://…/NorthwindService.svc/"))

‘Try to project just the properties we need:

Dim result = From c In svc.Categories Select c.CategoryID, c.CategoryName

For Each c In result ‘NotSupportedException when query executes

Console.WriteLine(c)

Next

    然而,我们得到一个运行时错误“选择不支持”,为了规划属性,我们只要执行查询和降低本地数据。然后突出那个清单,我们只需要像这样增加一个调用去扩展ToList方法:
Dim result = From c In svc.Categories.ToList Select c.CategoryID, c.CategoryName

不幸的是如果你在有效载荷查看所有返回的属性,虽然结果是我们想要的,但是确实最低效的,在我们的例子中,你可以看到图片的二进制数据返回,但从来没有使用过:

clip_image002

    我们真正想要的仅仅是在有效载荷里我们要求的那部分属性,幸运的是这些已经在Visual Studio 2010 和 .NET Framework 4中被支持了,另外你也可以在.NET 3.5中安装一个更新来获得这项支持,我们先通过在Visual Studio 2010中创建一个WCF数据服务工程来体验一下这个新特性吧。

Visual Studio 2010创建新的WCF数据服

    自从设计师在VS2008上做了一些微妙的改变后,我迫不及待的想要在VS2010上创建一个WCF数据服务。创建一个新的项目并选择网络节点,然后选择ASP.NET Web应用程序空。如果你没有看到它,请确保您的目标设置为.NET框架4。这是一个新的项目模板,以方便使用,特别是如果您创建数据服务。

clip_image004

    单击确定,创建项目。它将只包含一个web.config文件。接着像以前一样添加数据模型,因为我想使用实体框架,选择工程文件 à添加新项,选择数据节点,然后选择ADO.NET实体数据模型,单击添加就完成你的数据模型的创建了。依我而言,我从Northwind数据库中生成它。

    接下来,我们需要添加WCF的数据服务(前身是闻名的ADO.NET数据服务)。项目à “添加新项”,选择网络节点,然后向下滚动并选择WCF的数据服务。在试图寻找到它之前请确信此项目模板改名为.NET 3.5和4.0框架:

clip_image006

    现在,您可以设置您的实体访问。在这个例子中,我将在模型中访问所有的实体模型:

Public Class NorthwindService
    ' TODO: replace [[class name]] with your data class name
    Inherits DataService(Of NorthwindEntities)
 
    ' This method is called only once to initialize service-wide policies.
    Public Shared Sub InitializeService(ByVal config As DataServiceConfiguration)
        ' TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
        ' Examples:
        config.SetEntitySetAccessRule("*", EntitySetRights.AllRead)
        ' config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All)
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2
    End Sub
 

End Class

    最后,我们将添加一个简单的客户端控制台应用程序的解决方案测试服务。文件à添加à新建项目,然后选择控制台应用程序。右键单击控制台应用程序的客户端,然后选择“添加服务引用”在Solution Explorer。当打开对话框单击按钮,应探索找到数据服务。命名服务引用,然后单击确定。这将自动生成客户端代理和必要的实体来配合我们的数据服务。

使用WCF数据服务映射

    现在我们拥有一个.NET 4.0的WCF数据服务体制,我们可以在客户端写一个指定映射查询:

Dim svc As New NorthwindEntities(New Uri("http://.../NorthwindService.svc/"))
 
'Projections now supported in WCF Data Services 
Dim result = From c In svc.Categories Select c.CategoryID, c.CategoryName
 
For Each c In result 'No errors 
    Console.WriteLine(c)
Next
 
这意味着和以前不允许指定一个select参数相反,现在数据服务被支持了。如果你想用你喜欢的浏览器打开你的刚建好的WCF数据服务,您可以在查询字符串中指定一个查询分句:
http://…/NorthwindService.svc/Categories?$select=CategoryID,CategoryName
 

    现在如果你去查看有效负载,我们可以看到,只有CategoryID,CategoryName从服务端返回回来,这样就保护了系统资源。

clip_image008

    欲了解更多有关使用数据服务查询映射信息,请参阅MSDN LibraryWCF Data Services Team Blog