Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Распределённые приложения и сеть > WCF Data Services, Stored Procedure, Complex Type


Автор: eXplowar 11.3.2013, 11:56
Задача простая, выполнить хранимую процедуру с параметрами и получить результат.

В WCF хранимую процедуру реализую как в примере из книги http://my.safaribooksonline.com/book/programming/microsoft-dotnet/9781849685924/1dot-building-odata-services/id286697916#X2ludGVybmFsX0h0bWxWaWV3P3htbGlkPTk3ODE4NDk2ODU5MjQlMkZpZDI4NjY5NzkxNiZxdWVyeT0=

Проверяю решение в браузере вызовом своей SP с параметрами - работает.

Перехожу в клиентское приложение, пытаюсь вызвать ХП следующим образом:
Код

string uri = string.Format("http://localhost:4637/MainDataService.svc/uspGetOrdersByCustomer?customerId={0}", this.tbxUspGetOrdersByCustomer.Text);
IEnumerable<MainDataServiceReference.uspGetOrdersByCustomer_Result> ordersList = context.Execute<MainDataServiceReference.uspGetOrdersByCustomer_Result>(new Uri(uri));
this.dgOrdersByCustomer.ItemsSource = ordersList;

Попутно проверяю получение List<T>:
Код

IEnumerable<String> stringList = context.Execute<String>(new Uri("http://localhost:4637/MainDataService.svc/GetStringList"));
this.dgStringList.ItemsSource = stringList;

В OData 5.0.0 и OData 5.3.0 ошибки разные.

OData 5.0.0
    WCF Data Service Server (Microsoft.Data.Services) 5.0.0
    WCF Data Service Client (Microsoft.Data.Services.Client) 5.0.0
    ODataLib (Microsoft.Data.OData) 5.0.0
    EdmLib (Microsoft.Data.Edm) 5.0.0
    System.Spatial 5.0.0


GetStringList:
    В строковом значении обнаружен XML-узел типа "Element". Элемент со строковым значением может содержать только узлы Text, CDATA, SignificantWhitespace, Whitespace и Comment.

uspGetOrdersByCustomer:
    Свойство "element" не существует в типе "WpfApplication.MainDataServiceReference.uspGetOrdersByCustomer_Result". Используйте только имена свойств, определенные в типе.

OData 5.3.0
    WCF Data Service Server (Microsoft.Data.Services) 5.3.0
    WCF Data Service Client (Microsoft.Data.Services.Client) 5.3.0
    ODataLib (Microsoft.Data.OData) 5.3.0
    EdmLib (Microsoft.Data.Edm) 5.3.0
    System.Spatial 5.3.0


GetStringList:
    Невозможна материализация коллекции типов-примитивов или сложных типов без типа "Edm.String", который коллекцией.

uspGetOrdersByCustomer:
    Невозможна материализация коллекции типов-примитивов или сложных типов без типа "WpfApplication.MainDataServiceReference.uspGetOrdersByCustomer_Result", который коллекцией.

Data Services:
Код

public class TestDataService : DataService<EntityLib.MyEntities>
{
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.SetEntitySetAccessRule("*", EntitySetRights.All);
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
    }

    [WebGet]
    public int GetInt()
    {
        return 1;
    }

    [WebGet]
    public List<String> GetStringList()
    {
        List<String> myList = new List<String>();
        myList.Add("First string");
        myList.Add("Second string");
        myList.Add("Third string");

        return myList;
    }

    [WebGet]
    public IQueryable<EntityLib.Order> GetOrderById(int orderId)
    {
        var res = this.CurrentDataSource.Order.Where(o => o.OrderID == orderId);
        return res;
    }

    [WebGet]
    public IQueryable<EntityLib.uspGetOrdersByCustomer_Result> uspGetOrdersByCustomer(int customerId)
    {
        var res = CurrentDataSource.uspGetOrdersByCustomer(customerId).AsQueryable();
        return res;
    }
}

Client side:
Код

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        context = new DataServiceContext(new Uri("http://localhost:4637/MainDataService.svc/"));
    }

    DataServiceContext context;

    private void btnGetInt_Click(object sender, RoutedEventArgs e)
    {
        IEnumerable<int> varInt = context.Execute<int>(new Uri("http://localhost:4637/MainDataService.svc/GetInt"));
        this.tbckGetInt.Text = varInt.LastOrDefault().ToString();
    }

    private void btnGetStringList_Click(object sender, RoutedEventArgs e)
    {
        IEnumerable<String> stringList = context.Execute<String>(new Uri("http://localhost:4637/MainDataService.svc/GetStringList"));
        this.dgStringList.ItemsSource = stringList;
    }

    private void btnGetOrderById_Click(object sender, RoutedEventArgs e)
    {
        string uri = string.Format("http://localhost:4637/MainDataService.svc/GetOrderById?orderId={0}", this.tbxGetOrderById.Text);
        IEnumerable<MainDataServiceReference.Order> orderById = context.Execute<MainDataServiceReference.Order>(new Uri(uri));
        this.dgOrderById.ItemsSource = orderById;
    }

    private void btnUspGetOrdersByCustomer_Click(object sender, RoutedEventArgs e)
    {
        string uri = string.Format("http://localhost:4637/MainDataService.svc/uspGetOrdersByCustomer?customerId={0}", this.tbxUspGetOrdersByCustomer.Text);
        IEnumerable<MainDataServiceReference.uspGetOrdersByCustomer_Result> ordersList = context.Execute<MainDataServiceReference.uspGetOrdersByCustomer_Result>(new Uri(uri));
        this.dgOrdersByCustomer.ItemsSource = ordersList;
    }
}

Stored Procedure:
Код

CREATE PROCEDURE [dbo].[uspGetOrdersByCustomer](@customerId INT)
AS
BEGIN
    SET NOCOUNT ON;

    SELECT OrderID, CustomerID, OrderDate FROM dbo.[Order] WHERE (CustomerID = @customerId)
END


Метод GetOrderById работает, но он в отличии от моей хранимой процедуры возвращает не ComplexType, а EntityType.

Баг описан на http://connect.microsoft.com/VisualStudio/feedback/details/767210/wcf-service-opertation-unable-to-return-collection-of-type-enumerbale-string

Какие варианты можно применить в обход данной проблемы?

Проект: http://sdrv.ms/14Mcf2E

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)