Skip to content

Commit 95fe7b1

Browse files
author
Jeff Treuting
committed
Initial implementation of ODataRepository using re-linq
1 parent 4837ace commit 95fe7b1

41 files changed

Lines changed: 63689 additions & 343 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Newtonsoft.Json.Linq;
5+
using Remotion.Linq.Utilities;
6+
using SharpRepository.ODataRepository.Linq.QueryGeneration;
7+
8+
namespace SharpRepository.ODataRepository.Linq
9+
{
10+
public class ODataQuery
11+
{
12+
private readonly string _url;
13+
private readonly string _collectionName;
14+
private readonly QueryPartsAggregator _queryParts;
15+
16+
public ODataQuery(string url, string collectionName, QueryPartsAggregator queryParts)
17+
{
18+
_url = url;
19+
_collectionName = collectionName;
20+
_queryParts = queryParts;
21+
}
22+
23+
public IEnumerable<T> Enumerable<T>()
24+
{
25+
var querystring = String.Empty;
26+
var resultType = typeof (T);
27+
28+
if (_queryParts.ReturnCount)
29+
{
30+
querystring += "/$count";
31+
}
32+
33+
querystring += "?";
34+
35+
if (_queryParts.Take.HasValue)
36+
querystring += "$top=" + _queryParts.Take.Value + "&";
37+
38+
if (_queryParts.Skip.HasValue)
39+
querystring += "$skip=" + _queryParts.Skip.Value + "&";
40+
41+
if (!String.IsNullOrEmpty(_queryParts.OrderBy))
42+
querystring += "$orderby=" + _queryParts.OrderBy + "&";
43+
44+
var filter = SeparatedStringBuilder.Build(" and ", _queryParts.WhereParts);
45+
if (!String.IsNullOrEmpty(filter))
46+
querystring += "$filter=" + filter + "&";
47+
48+
if (!String.IsNullOrEmpty(_queryParts.SelectPart))
49+
querystring += "$select=" + _queryParts.SelectPart + "&";
50+
51+
var fullUrl = _url + "/" + _collectionName + querystring;
52+
var json = UrlHelper.Get(fullUrl);
53+
54+
//var json = ODataRequest.Execute(fullUrl, "POST", _queryParts.BuildODataApiPostData(), "application/json");
55+
56+
JObject res;
57+
// check for Count() [Int32] and LongCOunt() [Int64]
58+
if (_queryParts.ReturnCount && (resultType == typeof(Int32) || resultType == typeof(Int64)))
59+
{
60+
var results = new List<T>();
61+
62+
res = JObject.Parse(json);
63+
64+
results.Add(res["total_rows"].ToObject<T>());
65+
return results;
66+
}
67+
68+
// get the rows property and deserialize that
69+
res = JObject.Parse(json);
70+
var rows = res["rows"];
71+
72+
var items = rows.Select(row => row["value"].ToObject<T>());
73+
74+
return items;
75+
}
76+
}
77+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Remotion.Linq;
4+
using SharpRepository.ODataRepository.Linq.QueryGeneration;
5+
6+
namespace SharpRepository.ODataRepository.Linq
7+
{
8+
// Called by re-linq when a query is to be executed.
9+
public class ODataQueryExecutor : IQueryExecutor
10+
{
11+
private readonly string _url;
12+
private readonly string _databaseName;
13+
14+
public ODataQueryExecutor(string url, string databaseName)
15+
{
16+
_url = url;
17+
_databaseName = databaseName;
18+
}
19+
20+
// Executes a query with a scalar result, i.e. a query that ends with a result operator such as Count, Sum, or Average.
21+
public T ExecuteScalar<T> (QueryModel queryModel)
22+
{
23+
return ExecuteCollection<T> (queryModel).Single();
24+
}
25+
26+
// Executes a query with a single result object, i.e. a query that ends with a result operator such as First, Last, Single, Min, or Max.
27+
public T ExecuteSingle<T> (QueryModel queryModel, bool returnDefaultWhenEmpty)
28+
{
29+
return returnDefaultWhenEmpty ? ExecuteCollection<T> (queryModel).SingleOrDefault () : ExecuteCollection<T> (queryModel).Single ();
30+
}
31+
32+
// Executes a query with a collection result.
33+
public IEnumerable<T> ExecuteCollection<T> (QueryModel queryModel)
34+
{
35+
var commandData = ODataApiGeneratorQueryModelVisitor.GenerateODataApiQuery(queryModel);
36+
var query = commandData.CreateQuery(_url, _databaseName);
37+
return query.Enumerable<T> ();
38+
}
39+
}
40+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// ref: http://www.codeproject.com/Articles/42059/re-linq-ishing-the-Pain-Using-re-linq-to-Implement
2+
namespace SharpRepository.ODataRepository.Linq
3+
{
4+
public class ODataQueryFactory
5+
{
6+
public static ODataQueryable<T> Queryable<T>(string url, string databaseName)
7+
{
8+
return new ODataQueryable<T>(url, databaseName);
9+
}
10+
}
11+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.Linq;
2+
using System.Linq.Expressions;
3+
using Remotion.Linq;
4+
using Remotion.Linq.Parsing.Structure;
5+
6+
namespace SharpRepository.ODataRepository.Linq
7+
{
8+
/// <summary>
9+
/// Provides the main entry point to a LINQ query.
10+
/// </summary>
11+
public class ODataQueryable<T> : QueryableBase<T>
12+
{
13+
private static IQueryExecutor CreateExecutor (string url, string databaseName)
14+
{
15+
return new ODataQueryExecutor (url, databaseName);
16+
}
17+
18+
// This constructor is called by our users, create a new IQueryExecutor.
19+
public ODataQueryable (string url, string databaseName)
20+
: base (QueryParser.CreateDefault(), CreateExecutor (url, databaseName))
21+
{
22+
}
23+
24+
// This constructor is called indirectly by LINQ's query methods, just pass to base.
25+
public ODataQueryable(IQueryProvider provider, Expression expression)
26+
: base(provider, expression)
27+
{
28+
}
29+
}
30+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace SharpRepository.ODataRepository.Linq.QueryGeneration
2+
{
3+
public class CommandData
4+
{
5+
public CommandData(QueryPartsAggregator queryParts)
6+
{
7+
QueryParts = queryParts;
8+
}
9+
10+
public QueryPartsAggregator QueryParts { get; set; }
11+
12+
public ODataQuery CreateQuery(string url, string databaseName)
13+
{
14+
return new ODataQuery(url, databaseName, QueryParts);
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)