OData Client for .NET - 1.0

Extension ID

com.castsoftware.dotnet.odata

What’s new?

See OData Client for .NET - 1.0 - Release Notes.

Description

This extension provides support for OData client libraries when used inside .NET source code. 

In what situation should you install this extension?

If your .NET application source code uses the odata client libraries to consume OData services, you should install this extension.

Support

Supported Libraries

Library Name Library Version(s) OData Version(s)
Microsoft.OData.Client Upto 7.17 v4
Microsoft.Data.Services.Client Upto 5.8 v1-v3
Simple.OData.Client Upto 6.0 v1-v4

Supported APIs

OData v4 DataServiceQuery APIs
  • Microsoft.OData.Client.DataServiceQuery.Execute
  • Microsoft.OData.Client.DataServiceQuery.ExecuteAsync
OData v4 DataServiceContext APIs
  • Microsoft.OData.Client.DataServiceContext.AddObject
  • Microsoft.OData.Client.DataServiceContext.CreateQuery
  • Microsoft.OData.Client.DataServiceContext.DeleteObject
  • Microsoft.OData.Client.DataServiceContext.Execute
  • Microsoft.OData.Client.DataServiceContext.ExecuteBatch
  • Microsoft.OData.Client.DataServiceContext.UpdateObject
OData v1-v3 DataServiceQuery APIs
  • System.Data.Services.Client.DataServiceQuery.AddQueryOption
  • System.Data.Services.Client.DataServiceQuery.Execute
  • System.Data.Services.Client.DataServiceQuery.Expand
  • System.Data.Services.Client.DataServiceQuery.IncludeTotalCount
OData v1-v3 DataServiceContext APIs
  • System.Data.Services.Client.DataServiceContext.AddObject
  • System.Data.Services.Client.DataServiceContext.CreateQuery
  • System.Data.Services.Client.DataServiceContext.DeleteObject
  • System.Data.Services.Client.DataServiceContext.Execute
  • System.Data.Services.Client.DataServiceContext.UpdateObject
Simple.OData APIs
  • Simple.OData.Client.IBoundClient.FindEntriesAsync
  • Simple.OData.Client.IBoundClient.InsertEntriesAsync
  • Simple.OData.Client.IBoundClient.UpdateEntriesAsync
  • Simple.OData.Client.IBoundClient.DeleteEntriesAsync
  • Simple.OData.Client.IBoundClient.FindEntryAsync
  • Simple.OData.Client.IBoundClient.InsertEntryAsync
  • Simple.OData.Client.IBoundClient.UpdateEntryAsync
  • Simple.OData.Client.IBoundClient.DeleteEntryAsync
LINQ Enumerable APIs
  • System.Linq.Enumerable.All
  • System.Linq.Enumerable.Any
  • System.Linq.Enumerable.Append
  • System.Linq.Enumerable.AsEnumerable
  • System.Linq.Enumerable.Average
  • System.Linq.Enumerable.Cast
  • System.Linq.Enumerable.Chunk
  • System.Linq.Enumerable.Concat
  • System.Linq.Enumerable.Contains
  • System.Linq.Enumerable.Count
  • System.Linq.Enumerable.DefaultIfEmpty
  • System.Linq.Enumerable.Distinct
  • System.Linq.Enumerable.DistinctBy
  • System.Linq.Enumerable.ElementAt
  • System.Linq.Enumerable.ElementAtOrDefault
  • System.Linq.Enumerable.Except
  • System.Linq.Enumerable.ExceptBy
  • System.Linq.Enumerable.First
  • System.Linq.Enumerable.FirstOrDefault
  • System.Linq.Enumerable.GroupBy
  • System.Linq.Enumerable.GroupJoin
  • System.Linq.Enumerable.Intersect
  • System.Linq.Enumerable.IntersectBy
  • System.Linq.Enumerable.Join
  • System.Linq.Enumerable.Last
  • System.Linq.Enumerable.LastOrDefault
  • System.Linq.Enumerable.LongCount
  • System.Linq.Enumerable.Max
  • System.Linq.Enumerable.MaxBy
  • System.Linq.Enumerable.Min
  • System.Linq.Enumerable.MinBy
  • System.Linq.Enumerable.OfType
  • System.Linq.Enumerable.Order
  • System.Linq.Enumerable.OrderBy
  • System.Linq.Enumerable.OrderByDescending
  • System.Linq.Enumerable.OrderDescending
  • System.Linq.Enumerable.Prepend
  • System.Linq.Enumerable.Reverse
  • System.Linq.Enumerable.Select
  • System.Linq.Enumerable.SelectMany
  • System.Linq.Enumerable.SequenceEqual
  • System.Linq.Enumerable.Single
  • System.Linq.Enumerable.SingleOrDefault
  • System.Linq.Enumerable.Skip
  • System.Linq.Enumerable.SkipLast
  • System.Linq.Enumerable.SkipWhile
  • System.Linq.Enumerable.Sum
  • System.Linq.Enumerable.Take
  • System.Linq.Enumerable.TakeLast
  • System.Linq.Enumerable.TakeWhile
  • System.Linq.Enumerable.ThenBy
  • System.Linq.Enumerable.ThenByDescending
  • System.Linq.Enumerable.Union
  • System.Linq.Enumerable.UnionBy
  • System.Linq.Enumerable.Where
  • System.Linq.Enumerable.Zip
LINQ Queryable APIs
  • System.Linq.Queryable.All
  • System.Linq.Queryable.Any
  • System.Linq.Queryable.Append
  • System.Linq.Queryable.AsQueryable
  • System.Linq.Queryable.Average
  • System.Linq.Queryable.Cast
  • System.Linq.Queryable.Chunk
  • System.Linq.Queryable.Concat
  • System.Linq.Queryable.Contains
  • System.Linq.Queryable.Count
  • System.Linq.Queryable.DefaultIfEmpty
  • System.Linq.Queryable.Distinct
  • System.Linq.Queryable.DistinctBy
  • System.Linq.Queryable.ElementAt
  • System.Linq.Queryable.ElementAtOrDefault
  • System.Linq.Queryable.Except
  • System.Linq.Queryable.ExceptBy
  • System.Linq.Queryable.First
  • System.Linq.Queryable.FirstOrDefault
  • System.Linq.Queryable.GroupBy
  • System.Linq.Queryable.GroupJoin
  • System.Linq.Queryable.Intersect
  • System.Linq.Queryable.IntersectBy
  • System.Linq.Queryable.Join
  • System.Linq.Queryable.Last
  • System.Linq.Queryable.LastOrDefault
  • System.Linq.Queryable.LongCount
  • System.Linq.Queryable.Max
  • System.Linq.Queryable.MaxBy
  • System.Linq.Queryable.Min
  • System.Linq.Queryable.MinBy
  • System.Linq.Queryable.OfType
  • System.Linq.Queryable.Order
  • System.Linq.Queryable.OrderBy
  • System.Linq.Queryable.OrderByDescending
  • System.Linq.Queryable.OrderDescending
  • System.Linq.Queryable.Prepend
  • System.Linq.Queryable.Reverse
  • System.Linq.Queryable.Select
  • System.Linq.Queryable.SelectMany
  • System.Linq.Queryable.SequenceEqual
  • System.Linq.Queryable.Single
  • System.Linq.Queryable.SingleOrDefault
  • System.Linq.Queryable.Skip
  • System.Linq.Queryable.SkipLast
  • System.Linq.Queryable.SkipWhile
  • System.Linq.Queryable.Sum
  • System.Linq.Queryable.Take
  • System.Linq.Queryable.TakeLast
  • System.Linq.Queryable.TakeWhile
  • System.Linq.Queryable.ThenBy
  • System.Linq.Queryable.ThenByDescending
  • System.Linq.Queryable.Union
  • System.Linq.Queryable.UnionBy
  • System.Linq.Queryable.Where
  • System.Linq.Queryable.Zip

Function Point, Quality and Sizing support

This extension provides the following support:

Function Points (transactions) Quality and Sizing
✔️

AIP Core compatibility

AIP Core release Supported
8.3.x ✔️

What source code is needed by our analyzer?

For applications using Microsoft libraries, the OData extension requires the client proxy file, service reference file (.xml, .edmx etc.) generated by the code generation tool to function correctly. 

Dependencies with other extensions

Some CAST extensions require the presence of other CAST extensions in order to function correctly. The OData extension requires the following CAST extensions to be installed:

Any dependent extensions are automatically downloaded and installed. You do not need to do anything. The .NET Analyzer is not a dependency, but this extension will be automatically installed when .NET source code is delivered for analysis.

Download and installation instructions

For .NET applications using OData client libraries, the extension will be automatically installed by CAST Console. This is in place since October 2023.

For upgrade, if the Extension Strategy is not set to Auto update, you can manually install the extension using the Application - Extensions interface.

What results can you expect?

Objects

Icon Description
OData Client HttpRequest Get Service
OData Client HttpRequest Post Service
OData Client HttpRequest Put Service
OData Client HttpRequest Patch Service
OData Client HttpRequest Delete Service
Link Type Source and Destination
callLink Link from C# method making API call to service object (eg. OData Client HttpRequest Get Service)

Examples

Insert Operation

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.Services.Client;
using WpfApplication1.ServiceReference1;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                var svcUri = "http://localhost:52027/WcfDataService1.svc";
                var context = new castEntities(new Uri(svcUri));
                WpfApplication1.ServiceReference1.Table newProduct = WpfApplication1.ServiceReference1.Table.CreateTable(4);
                newProduct.Name = "Rian";
                context.AddObject("Tables", newProduct);
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private void buttonClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }
} 

Select Operation

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebApplication2.Models;


namespace odata_client_new
{
    class Program
    {
        static void Main(string[] args)
        {
            ListProduct().Wait();
        }

        static async Task ListProduct()
        {
            var serviceRoot = "http://localhost:64700/odata";
            var context = new Default.Container(new Uri(serviceRoot));

            IEnumerable<Product> products = await context.Products.ExecuteAsync();
            foreach (var product in products)
            {
                Console.WriteLine("{0} --- {1}", product.ID, product.Name);
            }
            
        }
    }
}  

Update Operation

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.Services.Client;
using WpfApplication1.ServiceReference1;
 
namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
 
        private void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                Uri svcUri = new Uri("http://localhost:52027/WcfDataService1.svc");
                context = new castEntities(svcUri);
                var data_to_change = (from table in context.Tables
                                  where table.Name == "Sam"
                                  select table).Single();
                data_to_change.Name = "Wiley";
                context.UpdateObject(data_to_change);
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private void buttonClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }
}

Delete Operation

using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebApplication2.Models;


namespace odata_client_new
{
    class Program
    {
        static void Main(string[] args)
        {
            DeleteCustomer().Wait();
        }


        static async Task DeleteCustomer()
        {
            var serviceRoot = "http://localhost:64700/odata";
            var context = new Default.Container(new Uri(serviceRoot));

            var customer = await context.Customers.ByKey(new Dictionary<string, object>() { { "ID", 002 } }).GetValue();
            Console.WriteLine(customer.Name);
            context.DeleteObject(customer);
            context.SaveChanges();
        }
    }
}

Universal Linker  is responsible for linking service object (eg. OData Client HttpRequest Get Service) to any matching operation objects. (Operation objects are generated by the analysis of server code, refer to com.castsoftware.dotnetweb ).

Limitations

  • For applications using Microsoft.OData.Client, only client code generated by OData Connected Service is supported.

  • For applications using Microsoft.OData.Client, methods like ‘ByKey’ which are defined in the auto-generated class ‘ExtensionMethods’ are not supported.

  • Actions and Functions are supported only for Simple.OData.Client.

  • For applications using Microsoft.Data.Services.Client, objects are not created for some code.

    Example

    Uri svcUri = new Uri("http://localhost:52027/WcfDataService1.svc");
    context = new castEntities(svcUri);
    DataServiceQuery<WpfApplication1.ServiceReference1.Customer> query = context.Customers;
    
    DataServiceCollection<WpfApplication1.ServiceReference1.Customer> records = new
        DataServiceCollection<WpfApplication1.ServiceReference1.Customer>(query);
    this.orderItemsGrid.DataContext = records;