簡單的實例來理解WCF 數據服務


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

        });

}

 

運行:

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

            ar.AsyncWaitHandle.WaitOne();

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

           

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

                {

                    dataGrid1.ItemsSource = products;

                });

        });

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM