服务器构架对象模型概述

[原文发表地址] Server Architecture Object Model Overview

[原文发表时间] 2011-06-06 07:00

下图展示了SharePoint Foundation服务器关于Microsoft.SharePoint.Administration命名空间的集合和对象的构架。

clip_image002[14]

1. SPFarm对象是SharePoint foundation对象模型层次结构中的根节点对象。Servers属性获取一个集合,来代表整个部署中所有的服务器,而Services属性则获取一个集合,来代表所有的服务。

2. 每个SPServer对象代表了一个物理服务器。ServiceInstances属性提供对运行在服务器上的一组服务实例的访问。

3. 每个SPService对象代表一个安装在服务器中的逻辑服务。派生的SPService类类型包括,例如,Windows服务对象,如定时服务,搜索,database服务等,以及Web服务对象,如支持Web应用的发布基本Web内容的服务。

4. SPWebService对象可以实现为特定逻辑服务或应用进行配置设置。WebApplications属性获取运行服务的Web应用集合。

5. 如果服务实现SharePoint Foundation的服务应用程序框架,它就可以被拆分成多个场范围内的配置实例(CFSIs)。每个配置实例都提供服务功能,但每个又有各自的权限和配置设定。

6. 每个在特定服务器上运行的服务实例,或者CFSI,都由一个SPServiceInstance对象代表。

7. SPDatabaseServiceInstance对象代表了运行于数据库服务器计算机上的独立的 数据库服务实例。SPDatabaseServiceInstance类派生自SPServiceInstance类,继承了服务属性,提供访问服务或应用程序的实例实施。Databases属性用于获取服务中使用的内容数据库集合。

8. 每个SPWebApplication对象代表了一个网络信息服务(IIS)网站上的Web应用。SPWebApplication对象支持对证书和其他场范围内的应用设置的访问。Sites属性在Web应用范围内获取网站集合,ContentDatabases属性则获取在Web应用中使用的内容数据库集合。

9. SPContentDatabase继承了SPDatabase类,且代表了包含Web应用用户数据的数据库。Sites属性获取网站集合的集成,为该内容数据库存储数据,而WebApplication属性则获取本源Web应用程序。

10. SPSiteCollection对象代表了在Web应用范围内的网站集合的集合

更多信息,请见服务器及站点构架:对象模型概述

创建较好用户体验的WPF DataGrid 列模板

[原文发表地址] Data Points – Composing WPF DataGrid Column Templates for a Better User Experience

最近一直在用WPF做客户端开发. 尽管我一直推崇使用第三方工具, 但有时也不使用第三方工具,为的是想体验一下那些由于某些原因坚持使用Visual Studio自带安装工具的开发者所面临的困难和挑战。

所以,我试着尝试了下WPF DataGrid. 尽管在做了很多搜索也浏览了很多论坛,还是花了好几天时间才解决了一些用户体验相关的问题。主要解决思想是为DataGrid各个列各自创建模板。因为这种解决方案不太为人所知,所以在这里共享给大家。

这篇文章会着重使用WPF控件ComboBox和DatePicker。

The DatePicker 和 New DataGrid Rows

使用DataGrid中的日期列令我感到沮丧。我通过在WPF窗口上拖了一个Object Data Source创建了DataGrid。设计器会为对象的每个DateTime日期类型的值默认创建一个DatePicker控件. 例如,为日期类型DateScheduled字段创建的一个列:

1.       <DataGridTemplateColumn x:Name=" dateScheduledColumn"  
2.         Header="DateScheduled" Width="100">
3.         <DataGridTemplateColumn.CellTemplate>
4.           <DataTemplate>
5.             <DatePicker
6.               SelectedDate="{Binding Path=DateScheduled, Mode=TwoWay,
7.                 ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
8.           </DataTemplate>
9.         </DataGridTemplateColumn.CellTemplate>
10.    </DataGridTemplateColumn>

这种默认的方式并不利于编辑。当编辑DatePicker控件时并不更新现有的数据行。它并不触发DataGrid的编辑,也就意味着不会通过数据绑定机制把变化传入底层的数据对象。解决办法是在绑定元素中增加UpdateSourceTrigger属性,并把值设成PropertyChanged:

1.       <DatePicker <DatePicker
2.          SelectedDate="{Binding Path= DateScheduled, Mode=TwoWay,
3.            ValidatesOnExceptions=true, NotifyOnValidationError=true,
4.            UpdateSourceTrigger=PropertyChanged}" />
 
 

尽管如此,相对新增加的数据行,DatePicker不能触发DataGrid的编辑模式的特点对新增加的数据行时候影响尤甚 。在DataGrid中一个新行由NewRowPlaceHolder表示。当第一次编辑新行的某个单元格时,编辑模式就会触发并把数据插入到数据源(再一次强调,不是数据库,而是底层的内存中的数据源)。因为DatePicker不触发编辑模式,所以这种数据更新也不会发生。

我也是很偶然的发现这个问题,因为第一列刚好是日期列。我本来是想靠这个来触发数据行的编辑模式。

图1 显示了当用户点击第一个可编辑的日期列时生成的新行

clip_image001

图 1 在新行输入一个日期Placeholder

但是当编辑完下一列的时候,之前编辑的值丢失了,参见图2

clip_image002

图 2 Task列被编辑时前面列的日期值丢失

第一列的键值变成了0,刚才输入的日期也变成了1/1/0001。当编辑Task列时才真最终触发DataGrid往数据源增加了一个实体。ID值变成了整数默认值0,日期变成了.net默认的最小日期1/1/0001。如果我有为这个类的日期设定一个默认值,用户输入的日期会变成类定义的默认日期,而不是.net 的日期默认值。注意Date Performed列没有变成默认值。这是因为DatePerformed是被定义成了一个可空的属性。

那么用户就得回头再去填Scheduled Date的值吗?我肯定用户不原意那么做。在这个问题上我挣扎了一下。我甚至把那日期列改写成使用了 DataTextBoxColumn控件, 但是这需要再写很多代码去处理验证等问题。

最后,WPF组的Varsha Mahadevan给我指了条出路。

WPF 可组合的特性使我们可以在一个列里使用两个元素。DataGridTemplateColumn不仅有CellTemplate元素,还有CellEditingTemplate元素。使用DatePicker来编辑而不需要触发DataGrid的编辑模式。而选择用TextBlock控件展示CellTemplate里面的日期。下面是针对dateScheduledCoumn 的新的XAML定义:

1. <DataGridTemplateColumn x:Name="dateScheduledColumn" 
2.   Header="Date Scheduled" Width="125">
3.   <DataGridTemplateColumn.CellTemplate>
4.     <DataTemplate>
5.       <TextBlock Text="{Binding Path= DateScheduled, StringFormat=\{0:d\}}" />
6.     </DataTemplate>
7.   </DataGridTemplateColumn.CellTemplate>
8.   <DataGridTemplateColumn.CellEditingTemplate>
9.     <DataTemplate>
10.             <DatePicker SelectedDate="{Binding Path=DateScheduled, Mode=TwoWay,
11.                         ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
12.           </DataTemplate>
13.         </DataGridTemplateColumn.CellEditingTemplate>
14.       </DataGridTemplateColumn>

注意我已经不再使用UpdateSourceTrigger属性了。也对DatePerformed列做了同样的变化。

现在日期列开始以简单文本的形式展现了,当你进入单元格编辑模式它就又会转换成DatePicker控件了,参见图3。

clip_image003

图 3 TextBlock DatePicker组成的DateScheduled

在新行上面的所有行,你都看不见有日期的图标。

但这也还不是很对。当编辑新行的时候我们仍然得到.net的默认值。现在你可以利用在底层类型中设置定义默认值而解决这个问题。我已经修改了ScheduleItem类的构造函数,用当前的日期作为默认值 来初始化新对象。如果有从数据库返回数据的话就覆盖它。在我的项目中,我是使用Entity Framework, 所有的类都是自动生成的。尽管如此,那些自动生成的类都标志成了部分实现(partial), 这就允许我在额外的部分实现类里面添加构造函数。

1. public partial class ScheduleItem
2.     {
3.       public ScheduleItem()
4.       {
5.         DateScheduled = DateTime.Today;
6.       }
7.     }

现在当我编辑新行的DateScheduled列时,DataGrid就会为我创建一个新的ScheduleItem实例,DatePicker控件会展示默认的日期(当前日期)。而当用户继续编辑行数据的时候,显示的 日期值会一直保持不变。

编辑时减少用户点击次数

用两部分组合方式的模板的一个坏处就是你必须在那个单元格上点击两次才能触发DatePicker控件。任何输入数据的人都会感到很沮丧,尤其是那些 不点鼠标而直接使用键盘输入数据的人。因为DatePicker控件被定义在编辑模板(editing template),只有当触发了编辑模式才会获得焦点—默认就这么设计的。这种设计适合TextBox等控件。但并不合适DatePicker。你可以使用XAML和后台代码的组合方式使得用户一聚焦到那个单元格就马上聚焦到DatePicker。

首先你需要在CellEditingTemplate中为DatePicker增加一个Grid容器。然后用WPF 的FocusManager使得当用户进入的时候就直接聚焦到该Grid容器。以下是新Grid容器包含着DatePicker的XAML:

1. <Grid FocusManager.FocusedElement="{Binding ElementName= dateScheduledPicker}">
2.   <DatePicker x:Name=" dateScheduledPicker" 
3.     SelectedDate="{Binding Path=DateScheduled, Mode=TwoWay,
4.     ValidatesOnExceptions=true, NotifyOnValidationError=true}"  />
5. </Grid>

注意我把DatePicker空间的名字绑定到了FocusedElement的ElementName。

现在我们回过头来看包含着DatePicker的DataGrid控件,注意我已经新增加了三个属性(RowDetailsVisibilityMode, SelectionMode 和SelectionUnit),以及一个新的事件处理(SelectedCellsChanged):

<DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True"

 

ItemsSource="{Binding}" Margin="12,12,22,31"

 

Name="scheduleItemsDataGrid"

 

RowDetailsVisibilityMode="VisibleWhenSelected"

 

SelectionMode="Extended" SelectionUnit="Cell"

 

SelectedCellsChanged="scheduleItemsDataGrid_SelectedCellsChanged">

 

当用户选择了一个单元格就会对DataGrid引发一个通知。最终,当这个发生时,你需要确认DataGrid是否真的进入了编辑模式,从而对DatePicker提供必要的光标和焦点。scheduleItemsDataGrid_SelectedCellsChanged 提供这个逻辑:

private void scheduleItemsDataGrid_SelectedCellsChanged

 

(object sender,

 

System.Windows.Controls.SelectedCellsChangedEventArgs e)

 

{

 

if (e.AddedCells.Count == 0) return;

 

var currentCell = e.AddedCells[0];

 

string header = (string)currentCell.Column.Header;

 

var currentCell = e.AddedCells[0];

 

if (currentCell.Column ==

 

scheduleItemsDataGrid.Columns[DateScheduledColumnIndex])

 

{

 

scheduleItemsDataGrid.BeginEdit();

 

}

 

}

 

注意,我已经在类定义的时候定义了常量DateScheduledColumnIndex等于1,表示在Grid中列的位置。

当这些全部到位后,我现在可以使用户满意了。

这确实花了不少时间来正确的让XAML和后台代码组合工作来使DatePicker很好的在DataGrid里面工作,也我希望能够帮你不必走弯路 。现在用户界面能够很人性化的工作起来了。

允许在一个受限的ComboBox显示额外的数据

当理解了DataGridTemplateColumn里元素的布局思想,我重新回顾了那个我快要放弃的关于ComboBox列在DataGrid里的问题。

这个应用程序是用来替代存有遗留数据的遗留系统的。这个遗留系统允许用户输入数据,但是控件不多。在系统里,客户要求有些数据项需要通过下拉列表进行输入。下拉列表里的数据可以简单的由一个字符串集合进行填充。难点在于那些可能不在这个字符串集合里的遗留数据也需要被显示在下拉列表里,(即使它并不包含在新的受限列表中)。

我第一次用DataGridComboBoxColumn尝试:

<DataGridComboBoxColumn x:Name="frequencyCombo"

 

MinWidth="100" Header="Frequency"

 

ItemsSource="{Binding Source={StaticResource frequencyViewSource}}"

 

SelectedValueBinding=

 

"{Binding Path=Frequency, UpdateSourceTrigger=PropertyChanged}">

 

</DataGridComboBoxColumn>

 

资源项在后台代码中定义:

private void PopulateTrueFrequencyList()

 

{

 

_frequencyList =

 

new List<String>{"",

 

"Initial","2 Weeks",

 

"1 Month", "2 Months",

 

"3 Months", "4 Months",

 

"5 Months", "6 Months",

 

"7 Months", "8 Months",

 

"9 Months", "10 Months",

 

"11 Months", "12 Months"

 

};

 

}

 

 

这个_frequencyList在另一个方法中被绑定到frequencyViewSource.Source属性。

尝试了各种对DataGrid Combo-Box列配置方法,我都没法让它显示那些可能存在只单独存在数据库里的Frequency字段。这里我也不打算把我的尝试一一列出,但其中有个尝试不得不提:把所有那些额外的值动态的加到_frequencyList列表的底部,再根据需要把它们从列表中移除 。在有更好的方法之前现在只能忍受这个。

我知道WPF分层的方法构造用户界面肯定提供了某种机制来解决这个问题,并且已经解决了DatePicker的问题,我意识到对于ComboBox或许可以用类似的解决方案。首先,弃用华而不实的DataGridComboBoxColumn而是更经典的用DataGridTemplateColumn里面嵌套ComboBox。然后,利用WPF的组合特性,你可以像之前的DateScheduled列一样在一个列模板里面使用两个元素。第一个是用来显示的TextBlock空间,另外一个是用来编辑的ComboBox。

图4 显示了如何把它们组合使用一起使用。

图 4 把一个用于显示的TextBlock和用于编辑的ComboBox组合一起使用

<DataGridTemplateColumn x:Name="taskColumnFaster"

 

Header="Task" Width="100" >

 

  <DataGridTemplateColumn.CellTemplate>

 

    <DataTemplate>

 

      <TextBlock Text="{Binding Path=Task}" />

 

    </DataTemplate>

 

  </DataGridTemplateColumn.CellTemplate>

 

  <DataGridTemplateColumn.CellEditingTemplate>

 

    <DataTemplate>

 

      <Grid FocusManager.FocusedElement=

 

"{Binding ElementName= taskCombo}" >

 

        <ComboBox x:Name="taskCombo"

 

        ItemsSource="{Binding Source={StaticResource taskViewSource}}"

 

        SelectedItem ="{Binding Path=Task}"

 

        IsSynchronizedWithCurrentItem="False"/>

 

      </Grid>

 

    </DataTemplate>

 

  </DataGridTemplateColumn.CellEditingTemplate>

 

</DataGridTemplateColumn>

 

TextBlock控件并不依赖于那个被限定的数据源列表,因此它可以显示任何存储在数据库的字段。尽管如此,编辑的时候也还是使用ComboBox,并且输入的项也仅限于frequencyViewSource里所有的值。

当单元格获得焦点的时候允许用户编辑

就像我们上面提到的,因为ComboBox只有被点击两次才能可用,所以为了能使用FocusManager使ComboBox在一开始就可用我把它放进了Grid里。

我修改了SelectedCellsChanged方法,使得当用户直接点击Task列而不用再移到第一列,就可以直接编辑新数据行。唯一的变化在于让代码也去检查当前的单元格是不是在Task列中。

private void scheduleItemsDataGrid_SelectedCellsChanged(object sender,

 

System.Windows.Controls.SelectedCellsChangedEventArgs e)

 

{

 

if (e.AddedCells.Count == 0) return;

 

var currentCell = e.AddedCells[0];

 

string header = (string)currentCell.Column.Header;

 

if (currentCell.Column ==

 

scheduleItemsDataGrid.Columns[DateScheduledColumnIndex]

 

|| currentCell.Column == scheduleItemsDataGrid.Columns[TaskColumnIndex])

 

{

 

scheduleItemsDataGrid.BeginEdit();

 

}

 

}

 

不要忽略用户体验

当我们开发者创建解决方案的时候,很正常的会专注在怎么确保数据的有效性 ,数据怎么流通或者其他类似的顾虑。我们很有可能没注意我们需要点击两次才能编辑日期。但用户就会很快的让你知道那个你为了提高他们工作效率而写的应用程序实际上是起了反作用,因为为了编辑那个数据他们需要鼠标键盘来来回回的额外操作。

Visual Studio 2010 WPF 数据绑定的这些特性很好节省了开发的时间,并通过对包含复杂数据类型的数据网格–尤其是包含了复杂的DatePicker和ComboBox空间–进行用户体验的微调,会极大的使你的用户感到满意。尽管他们不知道你在这上面所花的心思—但这就是我们工作的乐趣所在。

Course Manager示例第三部分—用户权限&管理员屏幕(Andy Kung)

Course Manager示例第三部分—用户权限&管理员屏幕(Andy Kung

[原文发表地址] Course Manager Sample Part 3 – User Permissions & Admin Screens (Andy Kung)

[原文发表时间] 20 Apr 2011 8:00 AM

Course Manager示例第二部分 – 设置数据,我们创建了表,关联,查询并了解了一些有用的数据定制。现在我们已经准备好创建屏幕了。我经常喜欢先做的事(作为一名LightSwitch开发人员)之一就是创建基础屏幕来输入并处理测试数据。对一个数据管理员来说,它们也是有用的终端用户屏幕。我把它们称为“未加工的数据界面”。显然地 ,我们不会给所有用户这些特别界面的访问权限的。它们应该是基于权限的。

在这篇博客中,我们将设置权限,创建一个未加工的数据界面,写出权限逻辑,并了解一些画面定制技术。让我们继续第二部分的“SimpleCourseManager”项目。

下载Course Manager示例应用程序

搭建应用程序

Course Manager是一个使用Windows身份认证的桌面应用程序。我们继续搭建工作。在解决方案资源管理器的属性上双击,打开应用程序设计器。

clip_image001[6]

应用程序类型

在“应用程序类型”选项卡中确保桌面已被选中(这是默认选项)。

clip_image002[6]

认证

在“访问控制权限”选项卡下选择“使用Windows身份认证”和“允许任意被认证的Windows用户”。顺便说下,“允许任意被认证的Windows用户”是Beta 2中引进的新功能。如果你要为公司的每位员工创建一个普通的应用程序,你不必再手动地为每个人创建用户账号了。相反,被认证了的Windows任意的用户都据有应用程序的访问权限。在这些普通权限(我们将要使用的)上你可以定义些特殊权限。

用户权限

在权限列表中你也会发现一个内置的SecruityAdministration。LightSwitch使用该权限显示或隐藏定义用户和角色的内置界面。作为开发人员,我想确保自己据有调试模式下的所有权限(那样我就可以看到所有的画面)。选中SecurityAdministration的“授予调试权限”选项。

clip_image003[6]

在列表中添加一个名为“ViewAdminScreen”的权限。我们以后会用它显示或隐藏我们的原始数据界面。再次选择“授予调试权限”选项。

clip_image004[6]

这时如果点击F5来启动运行的应用程序,你会在桌面应用程序的右下角看到Windows用户。同时也会看到据有内置角色和用户屏幕的管理菜单组(由于我们已经授权了调试模式的SecurityAdministration权限)。

clip_image005[6]

原始数据屏幕

现在我们就来创建第一个屏幕。在Students上创建一个名为“ManageStudents.”的列表和详细信息屏幕。

clip_image006[6]

在屏幕设计器上使用“写代码”下拉菜单选择ManageStudents_CanRun。这种方法定义了ManageStudents屏幕将会在正在运行的应用程序中显示出来。

clip_image007[6]

我们只想为据有ViewAdminScreen权限(在前几步中已经定义了的)的用户展示这个原始数据界面。在代码编辑器中写入:

Private Sub ManageStudents_CanRun(ByRef result As Boolean)

result = User.HasPermission(Permissions.ViewAdminScreen)

End Sub

再次敲下F5。我们将会看到刚创建的Students screen屏幕。默认情况下它是列在任务菜单组中的。让我们在管理菜单组中组织所有的原始数据界面。

clip_image008[6]

返回到LightSwitch IDE,打开应用程序设计器。在“屏幕导航”选项卡下从任务组中删除Manage Students屏幕并把它添加到管理组中。

clip_image009[6]

照着相同的步骤添加其他原始数据屏幕(据有ViewAdminScreen权限):

Screen Name

Screen Template

Screen Data

ManageStudents

List and Details

Students

ManageInstructors

List and Details

Instructors

ManageCategories

List and Details

Categories

ManageCourses

List and Details

Courses (include Sections, CourseCategories)

组织你的界面使它据有这个菜单架构。

clip_image010[6]

使用这些屏幕为students, instructors, categories, Courses 和sections输入示例数据

屏幕定制

在Course Manager示例项目中,我们也做了些屏幕定制来提高用户体验。这儿是些亮点:

学生管理

在“Manage Students”界面中,我们要做:

· 以链接的形式展示列表条目

· 对地址字段使用“Address Editor”控件

· 添加时间追踪字段并以只读文本框显示

clip_image011[6]

以链接形式显示列表项

在屏幕设计器中选择学生简介控件(在列表控件下)。在属性页选择“以链接形式显示”。

clip_image012[6]

对地址字段使用“Address Editor”控件

在屏幕设计器中右击“Student Details” 节点,选择“添加群”来添加一个群节点。

clip_image013[6]

更改群节点来使用“Address Editor”控件。

clip_image014[6]

现在拖动Street节点,把它放进去(STREET LINE 1)。在City, State, 和 Zip中重复拖动和放入操作。

clip_image015[6]

添加时间追踪字段并把它们以只读文本框显示

在屏幕设计器中选择“Student Details”节点。敲击“+ Add”按钮,选择“Created Time”来添加字段。重复进行,添加“Updated Time”和“Updated By”。

clip_image016[6]

使用命令行的“写代码”下拉菜单。选择ManageStudents_Created

clip_image017[6]

当屏幕上的UI元素被创建之后<Screen>_Created就可以被调用。我们想使它们为只读的。 写入:

Private Sub ManageStudents_Created()

FindControl("CreatedTime").IsReadOnly = True

FindControl("UpdatedTime").IsReadOnly = True

FindControl("UpdatedBy").IsReadOnly = True

End Sub

管理课程

在“Manage Courses”屏幕中,我们要做:

· 使用一个多行文本框作为描述字段(为TextBox控件设置行属性)

· 为多对多关系(查看“如何创建一个 多对多关系”)使用一个“List box mover” UI。

clip_image018[6]

总结

现在我们创建好了一个用Windows身份认证的功能桌面应用程序。我们也定义了权限逻辑来限制某些用于具有特权用户的屏幕。后面将要进行的是:Course Manager示例第四部分:实现工作流。

-andy

FILESTREAM 和 SharePoint 2010

[原文发表地址] FILESTREAM with SharePoint 2010

[原文发表时间] 3 May 2011 7:00 AM

FILESTREAM是SQL Server 2008中的一个新功能,它使得非结构化的数据能在NTFS文件系统中进行存储。在 sharepoint2010中支持FILESTREAM(本地或者远程)通过在内容可寻址或商业存储中存储大型的二进制非结构化数据,从而减少资金花费.

非结构化数据

非结构化数据指的是没有绑定到已定义的模型或不能很好适用于SharePoint关系表的信息,它可以是Microsoft Office文档文件格式,视频,音频,和相关的文件类型。

结构化数据

SharePoint中的结构化数据指的是和它对应的非结构化数据或BLOB相关联的元数据。关系数据库经常被作为结构化数据的例子。

SQL Server和非结构化数据存储

在SQL Server有三种方法用来存储非结构化数据,它们是 RBS,SQL BLOB和FILESTREAM:

· 远程BLOB存储器(RBS),在这个方法中SharePoint依赖SQL Server中的一个新层来读写存储于数据库之外的独立BLOB存储器(文件系统或专用的BLOB存储器)上的BLOB数据。

· SQL BLOB指的是SharePoint中传统的BLOB存储器, BLOB 数据与结构化的元数据一起被保存在内容数据库

  • FILESTREAM

FILESTREAM概述

FILESTREAM在varbinary(max)数据类型上实现,它告知数据库引擎在文件系统中存储非结构化的数据要通过包含有文件系统目录的FILESTREAM文件组,而不是文件本身(也称为数据容器)。数据容器是数据引擎存储器和文件系统存储器之间的接口。二进制数据类型varbinary是针对存储在SharePoint 2010内容数据库中的大型二进制对象而设计的,它指向 是可变长度二进制数据。(MAX)指的是最大值,即允许存储的最大值2^31-1字节或2GB。远程BLOB存储器并没有提供一种机制超出SharePoint限制的2GB文件大小。在SharePoint中,远程BLOB数据被RBS中的内容数据库中的唯一标识所引用(详见说明)。

clip_image001

FILESTREAM在性能方面有如下优点1)FILESTREAM使用NT系统缓存来缓存文件数据,从而减少对数据库引擎性能的影响2)没有使用SQL Server缓冲池;因此内存可被用于查询操作。

在用SharePoint存储大的BLOB数据时FILESTREAM的价值会得到体现,如视频文件或超过1MB的BLOB数据会从FILESTREAM中获益。

特殊考虑

FILESTREAM及业务可持续型管理

数据库镜像不支持FILESTREAM,这是由于不能在主服务器上创建FILESTREAM文件组,而且数据库镜像不能为包含FILESTREAM文件组的数据库配置。如果FILESTREAM提供程序被用来本地存储BLOB数据(在相同的内容数据库中),那么此数据库就不能配置为数据库镜像。

如果FILESTREAM提供程序用以在独立的SQL数据库或使用第三方BLOB存储器中存储BLOB数据,则内容数据库可以被镜像;然而,数据库镜像只应用在内容数据库中,而不用在BLOB数据中. BLOB数据需要被单独处理,并和对应的相关元数据(内容数据库中)保持同步。对于FILESTREAM BLOB数据库,可以通过日志传送来实现。

想了解FILESTREAM和SQL Server远程BLOB存储器之间的不同之处请查阅

http://blogs.msdn.com/b/sqlrbs/archive/2009/11/18/sql-server-remote-blob-store-and-filestream-feature-comparison.aspx.

FILESTREAM Office Web 应用程序缓存

Word和PowerPoint Web使用Office Web应用程序缓存来创建一个基于浏览器的文档版本,通过文档的缓存版本增加性能和减少服务器机器上的资源开销,或者使用Office Web应用程序缓存使得对相同文档进行多个请求得以实现。

Office Web应用程序缓存出现在两个不同层次,在服务器文件系统和基于每个网站应用程序的“特定的”站点集合上。正如图片呈现给用户的过程一样,文档和演示文稿请求要通过Office Web应用程序的两个缓存来实现。 当Office Web应用程序功能被启用时,Web应用程序中的所有网站集合都使用这两个缓存存储单元。

配置了FILESTREAM的内容数据库将会在配置文件指定的位置存储文档和演示文稿的副本。推荐在没有配置FILESTREAM的数据库上配置Office Web应用程序缓存。

SharePoint 2010配置FILESTREAM

下面的指导说明是用于以演示为目的的单服务器部署和实现本地FILESTREAM提供程序的。

在目标SQL Server实例上启用FILESTREAM

1.在开始菜单上,指向所有程序,指向Microsoft SQL Server 2008 (R2),指向配置工具,然后点击SQL Server配置管理器。

2.在服务清单中右击SQL Server服务,然后点打开

3.在SQL Server配置管理器嵌入式管理单元中,指出你想启用FILESTREAM的SQL Server实例的位置。

4.右击那个实例,选择属性

5.在SQL Server属性对话框中,点选FILESTREAM选项卡。

6.选择Enable FILESTREAM for Transact-SQL access复选框。

7.如果想要从Windows中读写FILESTREAM数据,点击Enable FILESTREAM for file I/O streaming access。在Windows Share Name框中输入Windows共享名字。

8.如果远程客户需要访问保存在这个共享上的FILESTREAM数据,选择允许远程客户访问FILESTREAM数据的权限。

9.点击应用。

10.点击开始,所有程序,Microsoft SQL Server 2008 (R2),然后点SQL Server Management Studio.

11.在SQL Server Management Studio中,点新查询打开查询编辑器。

12. 在查询编辑器中输入下面的Transact-SQL代码:

EXEC sp_configure filestream_access_level, 2

在查询编辑器中输入下面的Transact-SQL代码:RECONFIGURE

设置RBS数据存储器

1.点击开始,所有程序,Microsoft SQL Server 2008 (R2),然后点SQL Server Management Studio.

2.展开数据库。

3.选择你想创建BLOB存储器的内容数据库,然后点击新查询。

4.在SQL Server Management Studio中点击新查询打开查询编辑器。

5.在查询编辑器中,输入Transact-SQL代码:

use [Database Name]

if not exists (select * from sys.symmetric_keys where name = N’##MS_DatabaseMasterKey##’) create master key encryption by password password = N’Admin Key Password !2#4′

在查询编辑器中,输入Transact-SQL代码:

use [Database Name]

if not exists(select groupname from sysfilegroups where groupname=N’RBSFilestreamProvider’)alter database [Database Name] add filegroup RBSFilestreamProvider contains filestream

在查询编辑器中,输入Transact-SQL代码:

use [Database Name]

alter database [Database Name] add file (name = RBSFilestreamFile, filename = ‘c:\BlobStore’) to filegroup RBSFilestreamProvider

安装Microsoft SQL Server 2008 R2 Remote Blob Store

在Microsoft SQL Server 2008 R2功能包处http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ceb4346f-657f-4d28-83f5-aae0c5c83d52&displaylang=en下载Microsoft SQL Server 2008 R2 Remote Blob Store x64包,

以管理员权限打开命令行提示符,执行下面的命令来安装之前下载的RBS.MSI:

msiexec /qn /lvx* rbs_install_log.txt /i RBS.msi TRUSTSERVERCERTIFICATE=true FILEGROUP=PRIMARY DBNAME="<Database Name>" DBINSTANCE="<Instance Name>" FILESTREAMFILEGROUP=RBSFilestreamProvider FILESTREAMSTORENAME=FilestreamProvider_1

备注

在上面的声明中给RBS.MSI指定完整路径,即C:\Users\Administrator\Desktop\RBS.MSI。根据你需要的环境修改DBNAME 和DBINSTANCE的值。

启用远程BLOB存储器

1.在开始菜单上点击所有程序。

2.点击Microsoft SharePoint 2010 Products

3.点击SharePoint 2010 Management Shell

4.在SharePoint 2010 Management Shell中输入下面的Windows PowerShell语句来设置将要配置的内容数据库: $database=Get-SPContentDatabase –Identity “Database Name”

在SharePoint 2010 Management Shell中输入下面的Windows PowerShell语句来获取决定内容数据库如何使用Microsoft SQL Server Remote Blob存储器的执行环境的对象:

$rbs=$database.RemoteBlobStorageSettings

在SharePoint 2010 Management Shell中输入下面的Windows PowerShell语句来决定是否已经为选中的内容数据库安装了RBS:$rbs.Installed()

备注

$rbs.Installed()的结果应该是True,如果结果是False的话,可以通过审核rbs_install_log.txt来验证RBS.MSI是否已经成功地安装了。确保安装语句运行在SharePoint 2010 Management Shell下,输入下面的语句来为选中的内容数据库启用RBS:$rbs.Enable()

在SharePoint 2010 Management Shell中输入Windows PowerShell语句来为选中的内容数据库设置RBSprovider:$rbs.SetActiveProviderName($rbs.GetProviderNames()[0])

$rbs

备注

$rbs的结果是:

clip_image002

表1

表1的附件

Enabled指定对于选中的内容数据库RBS是否已启用。

ActiveProviderName是将要存入SQL Remote Blob存储器的新文件的名字。如果新文件没有用SQL Remote Blob存储器保存的话该项将会为空。

MinimumBlobStorageSize指的是考虑是否值得使用RBS存储的BLOB的最小尺寸,超出了指定的MinimumBlobStorageSize的BLOB数据将被保存到RBS。

FILESTREAM性能数据显示了超过1MB的BLOB数据具有最高效的流性能。请查看http://msdn.microsoft.com/en-us/library/cc949109(SQL.100).aspx

clip_image003

配置MinimumBlobStorageSize:

1.在开始菜单点击所有工程。

2.点击Microsoft SharePoint 2010 Products

3.点击SharePoint 2010 Management Shell

4.在SharePoint 2010 Management Shell中输入下面的Windows PowerShell语句来配置MinimumBlobStorageSize为1MB:

$database = Get-SPContentDatabase “Database Name”

$database.RemoteBlobStorageSettings.MinimumBlobStorageSize=1048576

$database.Update()

UpgradePersistedProperties指被删除或更改了的字段名或值的集合。

验证安装

验证FILESTREAM配置和RBS安装:

1.点击开始,点所有程序,接着点Microsoft SQL Server 2008,然后点SQL Server Management Studio

2.展开数据库。

3. 选择想要创建BLOB存储器的内容数据库,然后点击新查询。

4.在SQL Server Management Studio中,点击新查询打开查询编辑器。

5.在查询编辑器中输入下面的Transact-SQL代码:

USE [Database Name]

SELECT * FROM dbo.DatabaseInformation

保证RBSCollectionId和RBSProvider两行都可用。

测试RBS数据存储器

1.在一个网站的已配置好的内容数据库中选择一个想要的文档库。

2.上载一个大于1 MB的文件。

3.在有数据存储器的计算机上点击打开,然后点计算机。

4.浏览RBS数据存储器目录。

5.浏览文件并打开最近修改(而不是$FSLOG)的文件夹。在那个文件夹下打开最近修改的文件。验证这个文件和你上载的文件有相同的大小和内容。如果不同,请确认RBS已经正确安装并启用。

数据存储器 目录结构与下面的图例相似。

clip_image004

备注

当在上传一个大于MinimumBlobStorageSize的文档

出现事件错误:“ The URL ‘<Document Library>/File’ is invalid. It may refer to a nonexistent file or folder, or refer to a valid file or folder that is not in the current Web.”时,请打开SQL Server Configuration Manager,启用Enable FILESTREAM for file I/O streaming access并重新启动SQL Server (MSSQLSERVER)服务。

附加资源