1+ using System ;
2+ using System . Linq ;
3+ using System . Linq . Expressions ;
4+ using System . Reflection ;
5+ using System . Text . RegularExpressions ;
6+ using System . Threading . Tasks ;
7+ using Microsoft . Azure . Documents ;
8+ using Microsoft . Azure . Documents . Client ;
9+ using Microsoft . Azure . Documents . Linq ;
10+ using Newtonsoft . Json ;
11+ using Nito . AsyncEx . Synchronous ;
12+ using SharpRepository . Repository ;
13+ using SharpRepository . Repository . Caching ;
14+ using SharpRepository . Repository . FetchStrategies ;
15+ using SharpRepository . Repository . Helpers ;
16+ using SharpRepository . Repository . Specifications ;
17+
18+ namespace SharpRepository . AzureDocumentDb
19+ {
20+ public class DocumentDbRepositoryBase < T , TKey > : LinqRepositoryBase < T , TKey > where T : class , new ( )
21+ {
22+ protected DocumentClient Client { get ; set ; }
23+ protected Database Database { get ; set ; }
24+ protected DocumentCollection BaseCollection { get ; set ; }
25+ protected string CollectionId { get ; set ; }
26+
27+ internal DocumentDbRepositoryBase ( string endpointUrl , string authorizationKey , string databaseId , bool createIfNotExists , ICachingStrategy < T , TKey > cachingStrategy = null )
28+ : base ( cachingStrategy )
29+ {
30+ Client = new DocumentClient ( new Uri ( endpointUrl ) , authorizationKey ) ;
31+
32+ Initilize ( databaseId , createIfNotExists ) ;
33+ }
34+
35+ private void Initilize ( string databaseId , bool createIfNotExists )
36+ {
37+ Database = Client . CreateDatabaseQuery ( ) . Where ( db => db . Id == databaseId ) . AsEnumerable ( ) . FirstOrDefault ( ) ;
38+
39+ if ( Database == null && createIfNotExists )
40+ Database = DocumentDbRepositoryManager . CreateDatabase ( Client , databaseId ) . WaitAndUnwrapException ( ) ;
41+
42+ if ( Database == null )
43+ throw new Exception ( string . Format ( "No database {0} existed. Use createIfNotExists = true in order to create database." , databaseId ) ) ;
44+
45+ Regex rgx = new Regex ( "[^a-zA-Z0-9 -]" ) ;
46+ CollectionId = rgx . Replace ( typeof ( T ) . FullName , "" ) ;
47+
48+ BaseCollection =
49+ Client . CreateDocumentCollectionQuery ( Database . SelfLink )
50+ . Where ( c => c . Id == CollectionId )
51+ . ToArray ( )
52+ . FirstOrDefault ( ) ??
53+ DocumentDbRepositoryManager . CreateCollection ( Client , Database , CollectionId ) . WaitAndUnwrapException ( ) ;
54+ }
55+
56+ protected override Specification < T > CreateSpecification ( Expression < Func < T , bool > > lambda )
57+ {
58+ return new DocumentDbSpecification < T > ( lambda ) ;
59+ }
60+
61+ protected override IQueryable < T > BaseQuery ( IFetchStrategy < T > fetchStrategy = null )
62+ {
63+ return Client . CreateDocumentQuery < T > ( BaseCollection . DocumentsLink ) . AsQueryable ( ) ;
64+ }
65+
66+ protected virtual string GetSelfLink ( TKey id )
67+ {
68+ var propInfo = GetPrimaryKeyPropertyInfo ( ) ;
69+
70+ var parameter = Expression . Parameter ( typeof ( T ) , "x" ) ;
71+ var lambda = Expression . Lambda < Func < T , bool > > (
72+ Expression . Equal (
73+ Expression . PropertyOrField ( parameter , propInfo . Name ) ,
74+ Expression . Constant ( id )
75+ ) ,
76+ parameter
77+ ) ;
78+
79+ var query = Client . CreateDocumentQuery < Document > ( BaseCollection . DocumentsLink , string . Format ( "SELECT * FROM {0} e WHERE e.{1}" , CollectionId , lambda . ToMSSqlString ( ) ) ) ;
80+
81+ var doc = query . AsEnumerable ( ) . FirstOrDefault ( ) ;
82+
83+ if ( doc != null )
84+ return doc . SelfLink ;
85+
86+ return null ;
87+ }
88+
89+ protected override void AddItem ( T entity )
90+ {
91+ Client . CreateDocumentAsync ( BaseCollection . DocumentsLink , entity ) . WaitAndUnwrapException ( ) ;
92+ }
93+
94+ protected override void DeleteItem ( T entity )
95+ {
96+ TKey id ;
97+ if ( ! GetPrimaryKey ( entity , out id ) )
98+ return ;
99+
100+ var selfLink = GetSelfLink ( id ) ;
101+
102+ Client . DeleteDocumentAsync ( selfLink ) . WaitAndUnwrapException ( ) ;
103+ }
104+
105+ protected override void UpdateItem ( T entity )
106+ {
107+ TKey id ;
108+ if ( ! GetPrimaryKey ( entity , out id ) )
109+ return ;
110+
111+ var selfLink = GetSelfLink ( id ) ;
112+
113+ Client . ReplaceDocumentAsync ( selfLink , entity ) . WaitAndUnwrapException ( ) ;
114+ }
115+
116+ protected override PropertyInfo GetPrimaryKeyPropertyInfo ( )
117+ {
118+ // checks for the MongoDb BsonIdAttribute and if not there no the normal checks
119+ var type = typeof ( T ) ;
120+
121+ return type . GetProperties ( ) . FirstOrDefault ( x => x . HasAttribute < JsonPropertyAttribute > ( ) && x . GetCustomAttribute < JsonPropertyAttribute > ( ) . PropertyName . ToLower ( ) == "id" && x . PropertyType == typeof ( string ) )
122+ ?? base . GetPrimaryKeyPropertyInfo ( ) ;
123+ }
124+
125+ protected override void SaveChanges ( )
126+ {
127+ }
128+
129+ public override void Dispose ( )
130+ {
131+ Client . Dispose ( ) ;
132+ }
133+ }
134+ }
0 commit comments