简单的实例来理解WCF 数据服务(WCF DS)

Msdn解释:

image

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

 

实战:

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

image

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

image

image

image

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

clip_image012

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:所有一切都操作完毕后,可以在浏览器中查看。

image

 

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

 

 

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

 

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

image

2:添加服务引用:

image

 

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属性。

结果如下:

image

clip_image022

 

在这里可以看到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();

}

 

clip_image024

 

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

1:创建Silverlight应用程序

image

 

image

 

2MainPage.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>

 

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

clip_image030

3MainPage.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:运行,结果如下:

image

这是因为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);

}

 

再次运行:

image

 

 

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, nullnull);

    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, nullnull);

            ar.AsyncWaitHandle.WaitOne();

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

            dataGrid1.ItemsSource = products;

        });

}

 

运行:

clip_image036

原因如下:

clip_image038

 

最后完整的代码如下:

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, nullnull);

            ar.AsyncWaitHandle.WaitOne();

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

           

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

                {

                    dataGrid1.ItemsSource = products;

                });

        });

}


作者: LoveJenny

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值