Fork me on GitHub
简单的实例来理解WCF 数据服务

Msdn解释:

 

 

 

 

简而言之:如果使用WCF数据服务,就可以通过Rest的方式来访问和更改数据。

 

 

 

 

 

 

 

实战:

 

 

 

1:新建Asp.net 空Web应用程序:

 

 

 

 

2:因为WCF数据服务需要ado.net 实体,所以添加一个实体,命名为Northwind

 

 

 

 

 

 

3:添加了数据实体后,需要添加一个WCF数据服务

 

 

 

 

 

 

 

NorthwindWcfDataService.cs 代码如下:

 

 

 

namespace NorthwindDataServiceDemo

 

 

 

{

 

 

 

    public class NorthwindWcfDataService : DataService< /* TODO: 在此放置数据源类名*/ >

 

 

 

    {

 

 

 

        // 仅调用此方法一次以初始化涉及服务范围的策略。

 

 

 

        public static void InitializeService(DataServiceConfiguration config)

 

 

 

        {

 

 

 

            // TODO: 设置规则以指明哪些实体集和服务操作是可见的、可更新的,等等。

 

 

 

            // 示例:

 

 

 

            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);

 

 

 

            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);

 

 

 

            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

 

 

 

        }

 

 

 

    }

 

 

 

}

 

 

 

 

 

 

 

public class NorthwindWcfDataService : DataService< /* TODO: 在此放置数据源类名*/ >

 

 

 

在此放置数据源类名,在这里作为数据源的是Northwind.edmx 生成的NorthwindEntities。

 

 

 

将代码修改为:

 

 

 

 

public class NorthwindWcfDataService : DataService<NorthwindEntities>

 

 

 

 

 

 

 

 

因为需要设置规则来指明哪些实体集和服务操作是可见的、可更新的,等等。

 

 

 

 

 

 

 

所以将

 

 

 

// config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);

 

 

 

// config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);

 

 

 

修改为:

 

 

 

 

config.SetEntitySetAccessRule("*", EntitySetRights.All);

 

 

 

config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);

 

 

 

 

 

 

 

完整的代码如下:

 

 

 

namespace NorthwindDataServiceDemo

 

 

 

{

 

 

 

    public class NorthwindWcfDataService : DataService<NorthwindEntities>

 

 

 

    {

 

 

 

        // 仅调用此方法一次以初始化涉及服务范围的策略。

 

 

 

        public static void InitializeService(DataServiceConfiguration config)

 

 

 

        {

 

 

 

            // TODO: 设置规则以指明哪些实体集和服务操作是可见的、可更新的,等等。

 

 

 

            // 示例:

 

 

 

            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);

 

 

 

            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);

 

 

 

            config.SetEntitySetAccessRule("*", EntitySetRights.All);

 

 

 

            config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);

 

 

 

 

 

 

 

            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

 

 

 

        }

 

 

 

    }

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

4:所有一切都操作完毕后,可以在浏览器中查看。

 

 

 

 

 

 

 

 

好了,现在数据服务已经实现了,剩下的就是使用客户端来调用了。

 

 

 

 

 

 

 

 

 

 

 

创建控制台程序来调用WCF数据服务

 

 

 

 

 

 

 

1:添加控制台应用程序:

 

 

 

 

2:添加服务引用:

 

 

 

 

 

 

 

 

3:修改Program.cs 代码如下:

 

 

 

namespace NorthwindConsoleApp

 

 

 

{

 

 

 

    class Program

 

 

 

    {

 

 

 

        static void Main(string[] args)

 

 

 

        {

 

 

 

            Uri serviceRootUri = new Uri("http://localhost:34098/NorthwindWcfDataService.svc/");

 

 

 

            NorthwindService.NorthwindEntities northwindContext =

 

 

 

                new NorthwindService.NorthwindEntities(serviceRootUri);

 

 

 

 

 

 

 

            var products = northwindContext.Products.ToList();

 

 

 

 

 

 

 

            foreach (var product in products)

 

 

 

            {

 

 

 

                Console.WriteLine("{0},{1}", product.ProductID, product.ProductName);

 

 

 

            }

 

 

 

 

 

 

 

            Console.ReadLine();

 

 

 

        }

 

 

 

    }

 

 

 

}

 

 

 

 

 

 

 

这段代码主要是查询Products,

因为使用了WCF数据服务,所以客户端可以使用linq的方式来查询数据,从本质的角度来分析的话,不同的Linq查询在后台都会变成不同http请求地址,具体的请求地址可以查看RequestUri属性。

 

结果如下:

 

 

 

 

 

 

 

 

 

 

 

 

在这里可以看到Order_Details 的count 为0,

 

 

 

如果想要在查询Products的时候,同时查询所有的Order_Details 那么可以将代码修改如下:

 

 

 

var products = northwindContext.Products.ToList();

 

 

 

改为

 

 

 

var products = northwindContext.Products.Expand("Order_Details").ToList();

 

 

 

 

 

 

 

完整的代码如下:

 

 

 

static void Main(string[] args)

 

 

 

{

 

 

 

    Uri serviceRootUri = new Uri("http://localhost:34098/NorthwindWcfDataService.svc/");

 

 

 

    NorthwindService.NorthwindEntities northwindContext =

 

 

 

        new NorthwindService.NorthwindEntities(serviceRootUri);

 

 

 

 

 

 

 

    var products = northwindContext.Products.Expand("Order_Details").ToList();

 

 

 

 

 

 

 

    foreach (var product in products)

 

 

 

    {

 

 

 

        Console.WriteLine("id:{0},Name:{1},Orders:{2}",

 

 

 

            product.ProductID,

 

 

 

            product.ProductName,

 

 

 

            product.Order_Details.Count);

 

 

 

    }

 

 

 

 

 

 

 

    Console.ReadLine();

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3:使用Silverlight来调用WCF数据服务。

 

 

 

1:创建Silverlight应用程序

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2:MainPage.xaml 代码如下:

 

 

 

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  x:Class="NorthwindSilverlightApp.MainPage"

 

 

 

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

 

 

 

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

 

 

 

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

 

 

 

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

 

 

 

    mc:Ignorable="d"

 

 

 

    d:DesignHeight="300" d:DesignWidth="400">

 

 

 

 

 

 

 

    <Grid x:Name="LayoutRoot" Background="White">

 

 

 

        <Grid.RowDefinitions>

 

 

 

            <RowDefinition Height="Auto" />

 

 

 

            <RowDefinition Height="*" />

 

 

 

        </Grid.RowDefinitions>

 

 

 

 

 

 

 

        <StackPanel Grid.Row="0" HorizontalAlignment="Left" >

 

 

 

            <Button Content="First" Click="First_Click" />

 

 

 

        </StackPanel>

 

 

 

 

 

 

 

        <sdk:DataGrid Grid.Row="1" x:Name="dataGrid1" />

 

 

 

    </Grid>

 

 

 

</UserControl>

 

 

 

 

 

 

 

同理也需要添加服务引用:

 

 

 

 

 

 

 

3:MainPage.xaml.cs 代码如下:

 

 

 

 

 

 

 

namespace NorthwindSilverlightApp

 

 

 

{

 

 

 

    public partial class MainPage : UserControl

 

 

 

    {

 

 

 

        public MainPage()

 

 

 

        {

 

 

 

            InitializeComponent();

 

 

 

        }

 

 

 

 

 

 

 

        private void First_Click(object sender, RoutedEventArgs e)

 

 

 

        {

 

 

 

            Uri serviceRootUri = new Uri("http://localhost:34098/NorthwindWcfDataService.svc/");

 

 

 

            NorthwindService.NorthwindEntities northwindContext =

 

 

 

                new NorthwindService.NorthwindEntities(serviceRootUri);

 

 

 

 

 

 

 

            try

 

 

 

            {

 

 

 

                var products = northwindContext.Products.ToList();

 

 

 

                dataGrid1.ItemsSource = products;

 

 

 

            }

 

 

 

            catch(Exception ex)

 

 

 

            {

 

 

 

            MessageBox.Show(ex.Message);

 

 

 

            }

 

 

 

        }

 

 

 

    }

 

 

 

}

 

 

 

 

 

 

 

4:运行,结果如下:

 

 

 

 

这是因为Silverlight 只支持异步操作,而

 

 

 

var products = northwindContext.Products.ToList();

 

 

 

使用的是同步操作

 

 

 

修改First_Click 代码如下:

 

 

 

private void First_Click(object sender, RoutedEventArgs e)

 

 

 

{

 

 

 

    Uri serviceRootUri = new Uri("http://localhost:34098/NorthwindWcfDataService.svc/");

 

 

 

    NorthwindService.NorthwindEntities northwindContext =

 

 

 

        new NorthwindService.NorthwindEntities(serviceRootUri);

 

 

 

 

 

 

 

    var productsQuery = northwindContext.Products;

 

 

 

 

 

 

 

    northwindContext.BeginExecute<Product>(productsQuery.RequestUri,

 

 

 

        (ar) =>

 

 

 

        {

 

 

 

            var products = northwindContext.EndExecute<Product>(ar).ToList();

 

 

 

            dataGrid1.ItemsSource = products;

 

 

 

        },

 

 

 

        null);

 

 

 

}

 

 

 

 

 

 

 

再次运行:

 

 

 

 

 

 

 

 

 

 

 

 

 

Silverlight 的异步

 

 

 

 

修改MainPage.xaml 代码

 

 

 

<StackPanel Grid.Row="0" HorizontalAlignment="Left" Orientation="Horizontal" >

 

 

 

            <Button Content="First" Click="First_Click" />

 

 

 

            <Button Content="Second" Click="Second_Click" />

 

 

 

</StackPanel>

 

 

 

 

 

 

 

之所以我在First_Click 中使用匿名委托是有原因的,因为如果你尝试写下面的代码会阻塞浏览器。

 

 

 

private void Second_Click(object sender, RoutedEventArgs e)

 

 

 

{

 

 

 

    NorthwindService.NorthwindEntities northwindContext =

 

 

 

        new NorthwindService.NorthwindEntities(serviceRootUri);

 

 

 

 

 

 

 

    var productsQuery = northwindContext.Products;

 

 

 

 

 

 

 

    IAsyncResult ar = northwindContext.BeginExecute<Product>

 

 

 

                        (productsQuery.RequestUri, null, null);

 

 

 

    ar.AsyncWaitHandle.WaitOne();

 

 

 

    var products = northwindContext.EndExecute<Product>(ar).ToList();

 

 

 

    dataGrid1.ItemsSource = products;

 

 

 

}

 

 

 

 

 

 

 

这个问题的原因是ar.AsyncWaitHandle是在UI线程上执行的,所以会阻塞UI线程。

 

 

 

解决这个问题的方式也比较简单,使用ThreadPool或者是Task:

 

 

 

修改代码如下,使用ThreadPool

 

 

 

private void Second_Click(object sender, RoutedEventArgs e)

 

 

 

{

 

 

 

    NorthwindService.NorthwindEntities northwindContext =

 

 

 

        new NorthwindService.NorthwindEntities(serviceRootUri);

 

 

 

 

 

 

 

    var productsQuery = northwindContext.Products;

 

 

 

 

 

 

 

    ThreadPool.QueueUserWorkItem((obj) =>

 

 

 

        {

 

 

 

            IAsyncResult ar = northwindContext.BeginExecute<Product>

 

 

 

                                (productsQuery.RequestUri, null, null);

 

 

 

            ar.AsyncWaitHandle.WaitOne();

 

 

 

            var products = northwindContext.EndExecute<Product>(ar).ToList();

 

 

 

            dataGrid1.ItemsSource = products;

 

 

 

        });

 

 

 

}

 

 

 

 

 

 

 

运行:

 

 

 

 

 

 

 

原因如下:

 

 

 

 

 

 

 

 

 

 

 

最后完整的代码如下:

 

 

 

private void Second_Click(object sender, RoutedEventArgs e)

 

 

 

{

 

 

 

    NorthwindService.NorthwindEntities northwindContext =

 

 

 

        new NorthwindService.NorthwindEntities(serviceRootUri);

 

 

 

 

 

 

 

    var productsQuery = northwindContext.Products;

 

 

 

 

 

 

 

    ThreadPool.QueueUserWorkItem((obj) =>

 

 

 

        {

 

 

 

            IAsyncResult ar = northwindContext.BeginExecute<Product>

 

 

 

                                (productsQuery.RequestUri, null, null);

 

 

 

            ar.AsyncWaitHandle.WaitOne();

 

 

 

            var products = northwindContext.EndExecute<Product>(ar).ToList();

 

 

 

           

 

 

 

            Deployment.Current.Dispatcher.BeginInvoke(() =>

 

 

 

                {

 

 

 

                    dataGrid1.ItemsSource = products;

 

 

 

                });

 

 

 

        });

 

 

 

}

作者:LoveJenny
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted on   HackerVirus  阅读(316)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示