소스 검색

[CacheControl] V2.0

feature/authentication
Robin Thoni 9 년 전
부모
커밋
19171ce265

+ 12
- 1
CacheControl-test/CacheControl-test.csproj 파일 보기

@@ -43,6 +43,13 @@
43 43
       <SpecificVersion>False</SpecificVersion>
44 44
       <HintPath>..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
45 45
     </Reference>
46
+    <Reference Include="EntityFramework">
47
+      <HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll</HintPath>
48
+    </Reference>
49
+    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
50
+      <SpecificVersion>False</SpecificVersion>
51
+      <HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll</HintPath>
52
+    </Reference>
46 53
     <Reference Include="Microsoft.CSharp" />
47 54
     <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
48 55
       <SpecificVersion>False</SpecificVersion>
@@ -50,13 +57,14 @@
50 57
     </Reference>
51 58
     <Reference Include="System" />
52 59
     <Reference Include="System.Data" />
53
-    <Reference Include="System.Data.Entity" />
60
+    <Reference Include="System.Data.Linq" />
54 61
     <Reference Include="System.Drawing" />
55 62
     <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
56 63
       <SpecificVersion>False</SpecificVersion>
57 64
       <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
58 65
     </Reference>
59 66
     <Reference Include="System.Runtime.Serialization" />
67
+    <Reference Include="System.Security" />
60 68
     <Reference Include="System.Web.Entity" />
61 69
     <Reference Include="System.Web.ApplicationServices" />
62 70
     <Reference Include="System.ComponentModel.DataAnnotations" />
@@ -235,6 +243,9 @@
235 243
     <Content Include="packages.config" />
236 244
     <None Include="Project_Readme.html" />
237 245
   </ItemGroup>
246
+  <ItemGroup>
247
+    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
248
+  </ItemGroup>
238 249
   <PropertyGroup>
239 250
     <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
240 251
     <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

+ 2
- 3
CacheControl-test/Controllers/MyCacheOutputAttribute.cs 파일 보기

@@ -1,4 +1,4 @@
1
-using System.IO;
1
+using CacheControl.DBO;
2 2
 using iiie.CacheControl.Business.Attributes;
3 3
 using iiie.CacheControl.Business.OutputCache;
4 4
 
@@ -8,8 +8,7 @@ namespace CacheControl_test.Controllers
8 8
     {
9 9
         public MyCacheOutputAttribute(int seconds) : base(seconds)
10 10
         {
11
-            CacheOutputData = Path.Combine(Path.GetTempPath(), "cache-control-test");
12
-            CacheType = OutputCacheType.File;
11
+            CacheType = OutputCacheType.DataBase;
13 12
         }
14 13
     }
15 14
 }

+ 24
- 3
CacheControl-test/Web.config 파일 보기

@@ -4,6 +4,10 @@
4 4
   http://go.microsoft.com/fwlink/?LinkId=301879
5 5
   -->
6 6
 <configuration>
7
+  <configSections>
8
+    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
9
+    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
10
+  </configSections>
7 11
   <appSettings>
8 12
     <add key="webpages:Version" value="3.0.0.0" />
9 13
     <add key="webpages:Enabled" value="false" />
@@ -14,7 +18,6 @@
14 18
     <compilation debug="true" targetFramework="4.5" />
15 19
     <httpRuntime targetFramework="4.5" />
16 20
   </system.web>
17
-  
18 21
   <runtime>
19 22
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
20 23
       <dependentAssembly>
@@ -41,13 +44,31 @@
41 44
         <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
42 45
         <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
43 46
       </dependentAssembly>
47
+      <dependentAssembly>
48
+        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
49
+        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
50
+      </dependentAssembly>
44 51
     </assemblyBinding>
45 52
   </runtime>
46
-<system.webServer>
53
+  <system.webServer>
47 54
     <handlers>
48 55
       <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
49 56
       <remove name="OPTIONSVerbHandler" />
50 57
       <remove name="TRACEVerbHandler" />
51 58
       <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
52 59
     </handlers>
53
-  </system.webServer></configuration>
60
+  </system.webServer>
61
+  <connectionStrings>
62
+    <add name="CacheControlEntities" connectionString="metadata=res://*/DataAccess.CacheEntities.csdl|res://*/DataAccess.CacheEntities.ssdl|res://*/DataAccess.CacheEntities.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=CacheControl;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
63
+  </connectionStrings>
64
+  <entityFramework>
65
+    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
66
+      <parameters>
67
+        <parameter value="v11.0" />
68
+      </parameters>
69
+    </defaultConnectionFactory>
70
+    <providers>
71
+      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
72
+    </providers>
73
+  </entityFramework>
74
+</configuration>

+ 1
- 0
CacheControl-test/packages.config 파일 보기

@@ -2,6 +2,7 @@
2 2
 <packages>
3 3
   <package id="Antlr" version="3.5.0.2" targetFramework="net45" />
4 4
   <package id="bootstrap" version="3.3.4" targetFramework="net45" />
5
+  <package id="EntityFramework" version="6.1.3" targetFramework="net45" />
5 6
   <package id="jQuery" version="2.1.4" targetFramework="net45" />
6 7
   <package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
7 8
   <package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />

+ 20
- 0
CacheControl/App.config 파일 보기

@@ -0,0 +1,20 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<configuration>
3
+  <configSections>
4
+    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
5
+    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
6
+  </configSections>
7
+  <entityFramework>
8
+    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
9
+      <parameters>
10
+        <parameter value="v11.0" />
11
+      </parameters>
12
+    </defaultConnectionFactory>
13
+    <providers>
14
+      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
15
+    </providers>
16
+  </entityFramework>
17
+  <connectionStrings>
18
+    <add name="CacheControlEntities" connectionString="metadata=res://*/DataAccess.CacheEntities.csdl|res://*/DataAccess.CacheEntities.ssdl|res://*/DataAccess.CacheEntities.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=CacheControl;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
19
+  </connectionStrings>
20
+</configuration>

+ 2
- 7
CacheControl/Business/Attributes/CacheControlAttribute.cs 파일 보기

@@ -27,11 +27,6 @@ namespace iiie.CacheControl.Attributes
27 27
         /// </summary>
28 28
         protected bool MustRevalidate { get; set; }
29 29
 
30
-        /// <summary>
31
-        /// Data used by OutputCache
32
-        /// </summary>
33
-        protected object CacheOutputData { get; set; }
34
-
35 30
         /// <summary>
36 31
         /// Indicates if the query string must be used to control cache
37 32
         /// </summary>
@@ -50,7 +45,7 @@ namespace iiie.CacheControl.Attributes
50 45
 
51 46
         protected void EnsureCache(HttpConfiguration config, HttpRequestMessage req)
52 47
         {
53
-            _webCache = config.CacheOutputConfiguration(CacheType).GetCacheOutputProvider(req, CacheOutputData);
48
+            _webCache = config.CacheOutputConfiguration(CacheType).GetCacheOutputProvider(req);
54 49
         }
55 50
 
56 51
         protected abstract bool IsValid(CacheDbo data);
@@ -104,7 +99,7 @@ namespace iiie.CacheControl.Attributes
104 99
 
105 100
             var cachekey = cacheKeyGenerator.MakeCacheKey(actionContext, _responseMediaType, CacheType, ExcludeQueryStringFromCacheKey);
106 101
 
107
-            var data = _webCache.Get<CacheDbo>(cachekey);
102
+            var data = _webCache.Get(cachekey);
108 103
             if (data == null)
109 104
                 return;
110 105
 

+ 4
- 3
CacheControl/Business/HttpExtensions/CacheOutputConfiguration.cs 파일 보기

@@ -4,6 +4,7 @@ using System.Linq.Expressions;
4 4
 using System.Net.Http;
5 5
 using System.Reflection;
6 6
 using System.Web.Http;
7
+using CacheControl.DBO;
7 8
 using iiie.CacheControl.Business.CacheKey;
8 9
 using iiie.CacheControl.Business.OutputCache;
9 10
 
@@ -89,7 +90,7 @@ namespace iiie.CacheControl.Business.HttpExtensions
89 90
                 ?? new DefaultCacheKeyGenerator();
90 91
         }
91 92
 
92
-        public IOutputCache GetCacheOutputProvider(HttpRequestMessage request, object cacheOutputData)
93
+        public IOutputCache GetCacheOutputProvider(HttpRequestMessage request)
93 94
         {
94 95
             object cache;
95 96
             _configuration.Properties.TryGetValue(typeof(IOutputCache), out cache);
@@ -99,8 +100,8 @@ namespace iiie.CacheControl.Business.HttpExtensions
99 100
             var cacheOutputProvider = cacheFunc != null ? cacheFunc() : request.GetDependencyScope().GetService(typeof(IOutputCache)) as IOutputCache;
100 101
             if (cacheOutputProvider == null)
101 102
             {
102
-                if (_cacheType == OutputCacheType.File)
103
-                    cacheOutputProvider = new FileOuputCache(cacheOutputData as string);
103
+                if (_cacheType == OutputCacheType.DataBase)
104
+                    cacheOutputProvider = new DbOutputCache();
104 105
                 else
105 106
                     cacheOutputProvider = new MemoryOutputCache();
106 107
             }

+ 65
- 0
CacheControl/Business/OutputCache/DbOutputCache.cs 파일 보기

@@ -0,0 +1,65 @@
1
+using System;
2
+using System.Linq;
3
+using CacheControl.DataAccess;
4
+using iiie.CacheControl.DBO;
5
+
6
+namespace iiie.CacheControl.Business.OutputCache
7
+{
8
+    public class DbOutputCache : IOutputCache
9
+    {
10
+
11
+        public override CacheDbo Get(string key)
12
+        {
13
+            using (var db = new CacheControlEntities())
14
+            {
15
+                var item = db.T_Cache.FirstOrDefault(x => x.cachekey == key);
16
+                if (item == null)
17
+                    return null;
18
+                return new CacheDbo
19
+                {
20
+                    Date = item.date,
21
+                    ETag = item.etag,
22
+                    Content = item.content,
23
+                    ContentType = item.content_type
24
+                };
25
+            }
26
+        }
27
+
28
+        public override void Remove(string key)
29
+        {
30
+            using (var db = new CacheControlEntities())
31
+            {
32
+                var item = db.T_Cache.FirstOrDefault(x => x.cachekey == key);
33
+                if (item != null)
34
+                {
35
+                    db.T_Cache.Remove(item);
36
+                    db.SaveChanges();
37
+                }
38
+            }
39
+        }
40
+
41
+        public override bool Contains(string key)
42
+        {
43
+            using (var db = new CacheControlEntities())
44
+            {
45
+                return db.T_Cache.Any(x => x.cachekey == key);
46
+            }
47
+        }
48
+
49
+        public override void Add(string key, CacheDbo o)
50
+        {
51
+            using (var db = new CacheControlEntities())
52
+            {
53
+                db.T_Cache.Add(new T_Cache
54
+                {
55
+                    cachekey = key,
56
+                    etag = o.ETag,
57
+                    content = o.Content,
58
+                    date = o.Date,
59
+                    content_type = o.ContentType
60
+                });
61
+                db.SaveChanges();
62
+            }
63
+        }
64
+    }
65
+}

+ 0
- 74
CacheControl/Business/OutputCache/FileOuputCache.cs 파일 보기

@@ -1,74 +0,0 @@
1
-using System;
2
-using System.IO;
3
-using System.Runtime.Serialization.Formatters.Binary;
4
-using System.Web;
5
-
6
-namespace iiie.CacheControl.Business.OutputCache
7
-{
8
-    public class FileOuputCache : IOutputCache
9
-    {
10
-        private string TempPath { get; set; }
11
-
12
-        public FileOuputCache(string tempPath)
13
-        {
14
-            TempPath = tempPath;
15
-        }
16
-
17
-        public string GetPath(string key)
18
-        {
19
-            key = HttpUtility.UrlEncode(key);
20
-            if (!Directory.Exists(TempPath))
21
-                Directory.CreateDirectory(TempPath);
22
-            return Path.Combine(TempPath, key);
23
-        }
24
-
25
-        public override object Get(string key)
26
-        {
27
-            try
28
-            {
29
-                var path = GetPath(key);
30
-                var formatter = new BinaryFormatter();
31
-                var stream = new FileStream(path, FileMode.Open);
32
-                var obj = formatter.Deserialize(stream);
33
-                stream.Close();
34
-                return obj;
35
-            }
36
-            catch (Exception)
37
-            {
38
-                return null;
39
-            }
40
-        }
41
-
42
-        public override void Remove(string key)
43
-        {
44
-            var path = GetPath(key);
45
-            File.Delete(path);
46
-        }
47
-
48
-        public override bool Contains(string key)
49
-        {
50
-            var path = GetPath(key);
51
-            return File.Exists(path);
52
-        }
53
-
54
-        public override void Add(string key, object o)
55
-        {
56
-            FileStream stream = null;
57
-            try
58
-            {
59
-                var path = GetPath(key);
60
-                var formatter = new BinaryFormatter();
61
-                stream = new FileStream(path, FileMode.OpenOrCreate);
62
-                formatter.Serialize(stream, o);
63
-                stream.Close();
64
-                stream = null;
65
-            }
66
-            catch (Exception e)
67
-            {
68
-                if (stream != null)
69
-                    stream.Close();
70
-                Remove(key);
71
-            }
72
-        }
73
-    }
74
-}

+ 4
- 9
CacheControl/Business/OutputCache/IOutputCache.cs 파일 보기

@@ -1,20 +1,15 @@
1
-
1
+using iiie.CacheControl.DBO;
2
+
2 3
 namespace iiie.CacheControl.Business.OutputCache
3 4
 {
4 5
     public abstract class IOutputCache
5 6
     {
6
-        public virtual T Get<T>(string key) where T : class
7
-        {
8
-            var o = Get(key) as T;
9
-            return o;
10
-        }
11
-
12
-        public abstract object Get(string key);
7
+        public abstract CacheDbo Get(string key);
13 8
 
14 9
         public abstract void Remove(string key);
15 10
 
16 11
         public abstract bool Contains(string key);
17 12
 
18
-        public abstract void Add(string key, object o);
13
+        public abstract void Add(string key, CacheDbo o);
19 14
     }
20 15
 }

+ 4
- 3
CacheControl/Business/OutputCache/MemoryOutputCache.cs 파일 보기

@@ -1,4 +1,5 @@
1 1
 using System.Runtime.Caching;
2
+using iiie.CacheControl.DBO;
2 3
 
3 4
 namespace iiie.CacheControl.Business.OutputCache
4 5
 {
@@ -6,9 +7,9 @@ namespace iiie.CacheControl.Business.OutputCache
6 7
     {
7 8
         private static readonly MemoryCache Cache = MemoryCache.Default;
8 9
 
9
-        public override object Get(string key)
10
+        public override CacheDbo Get(string key)
10 11
         {
11
-            return Cache.Get(key);
12
+            return Cache.Get(key) as CacheDbo;
12 13
         }
13 14
 
14 15
         public override void Remove(string key)
@@ -24,7 +25,7 @@ namespace iiie.CacheControl.Business.OutputCache
24 25
             return Cache.Contains(key);
25 26
         }
26 27
 
27
-        public override void Add(string key, object o)
28
+        public override void Add(string key, CacheDbo o)
28 29
         {
29 30
             lock (Cache)
30 31
             {

+ 2
- 2
CacheControl/Business/OutputCache/OutputCacheType.cs 파일 보기

@@ -12,8 +12,8 @@ namespace iiie.CacheControl.Business.OutputCache
12 12
         Memory,
13 13
 
14 14
         /// <summary>
15
-        /// Cache is stroed in a temp file
15
+        /// Cache is stored in a database
16 16
         /// </summary>
17
-        File
17
+        DataBase
18 18
     }
19 19
 }

+ 53
- 1
CacheControl/CacheControl.csproj 파일 보기

@@ -30,11 +30,18 @@
30 30
     <WarningLevel>4</WarningLevel>
31 31
   </PropertyGroup>
32 32
   <ItemGroup>
33
+    <Reference Include="EntityFramework">
34
+      <HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll</HintPath>
35
+    </Reference>
36
+    <Reference Include="EntityFramework.SqlServer">
37
+      <HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll</HintPath>
38
+    </Reference>
33 39
     <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
34 40
       <SpecificVersion>False</SpecificVersion>
35 41
       <HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
36 42
     </Reference>
37 43
     <Reference Include="System" />
44
+    <Reference Include="System.ComponentModel.DataAnnotations" />
38 45
     <Reference Include="System.Core" />
39 46
     <Reference Include="System.Net.Http" />
40 47
     <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -42,6 +49,8 @@
42 49
       <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
43 50
     </Reference>
44 51
     <Reference Include="System.Runtime.Caching" />
52
+    <Reference Include="System.Runtime.Serialization" />
53
+    <Reference Include="System.Security" />
45 54
     <Reference Include="System.Web" />
46 55
     <Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
47 56
       <SpecificVersion>False</SpecificVersion>
@@ -64,16 +73,59 @@
64 73
     <Compile Include="Business\CacheKey\ICacheKeyGenerator.cs" />
65 74
     <Compile Include="Business\HttpExtensions\CacheOutputConfiguration.cs" />
66 75
     <Compile Include="Business\HttpExtensions\HttpConfigurationExtensions.cs" />
67
-    <Compile Include="Business\OutputCache\FileOuputCache.cs" />
76
+    <Compile Include="Business\OutputCache\DbOutputCache.cs" />
68 77
     <Compile Include="Business\OutputCache\IOutputCache.cs" />
69 78
     <Compile Include="Business\OutputCache\MemoryOutputCache.cs" />
70 79
     <Compile Include="Business\OutputCache\OutputCacheType.cs" />
80
+    <Compile Include="DataAccess\CacheEntities.Context.cs">
81
+      <AutoGen>True</AutoGen>
82
+      <DesignTime>True</DesignTime>
83
+      <DependentUpon>CacheEntities.Context.tt</DependentUpon>
84
+    </Compile>
85
+    <Compile Include="DataAccess\CacheEntities.cs">
86
+      <AutoGen>True</AutoGen>
87
+      <DesignTime>True</DesignTime>
88
+      <DependentUpon>CacheEntities.tt</DependentUpon>
89
+    </Compile>
90
+    <Compile Include="DataAccess\CacheEntities.Designer.cs">
91
+      <AutoGen>True</AutoGen>
92
+      <DesignTime>True</DesignTime>
93
+      <DependentUpon>CacheEntities.edmx</DependentUpon>
94
+    </Compile>
95
+    <Compile Include="DataAccess\T_Cache.cs">
96
+      <DependentUpon>CacheEntities.tt</DependentUpon>
97
+    </Compile>
71 98
     <Compile Include="DBO\CacheDbo.cs" />
99
+    <Compile Include="DBO\DbOutputCacheDbo.cs" />
72 100
     <Compile Include="Properties\AssemblyInfo.cs" />
73 101
   </ItemGroup>
74 102
   <ItemGroup>
103
+    <None Include="App.config" />
104
+    <EntityDeploy Include="DataAccess\CacheEntities.edmx">
105
+      <Generator>EntityModelCodeGenerator</Generator>
106
+      <LastGenOutput>CacheEntities.Designer.cs</LastGenOutput>
107
+    </EntityDeploy>
108
+    <None Include="DataAccess\CacheEntities.Context.tt">
109
+      <Generator>TextTemplatingFileGenerator</Generator>
110
+      <DependentUpon>CacheEntities.edmx</DependentUpon>
111
+      <LastGenOutput>CacheEntities.Context.cs</LastGenOutput>
112
+    </None>
113
+    <None Include="DataAccess\CacheEntities.edmx.diagram">
114
+      <DependentUpon>CacheEntities.edmx</DependentUpon>
115
+    </None>
116
+    <None Include="DataAccess\CacheEntities.tt">
117
+      <Generator>TextTemplatingFileGenerator</Generator>
118
+      <DependentUpon>CacheEntities.edmx</DependentUpon>
119
+      <LastGenOutput>CacheEntities.cs</LastGenOutput>
120
+    </None>
75 121
     <None Include="packages.config" />
76 122
   </ItemGroup>
123
+  <ItemGroup>
124
+    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
125
+  </ItemGroup>
126
+  <ItemGroup>
127
+    <Content Include="DataAccess\schema.txt" />
128
+  </ItemGroup>
77 129
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
78 130
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
79 131
        Other similar extension points exist, see Microsoft.Common.targets.

+ 1
- 1
CacheControl/CacheControl.nuspec 파일 보기

@@ -2,7 +2,7 @@
2 2
 <package >
3 3
   <metadata>
4 4
     <id>3ieCacheControl.dll</id>
5
-    <version>1.0.0</version>
5
+    <version>2.0.0</version>
6 6
     <title>3ie Cache Control</title>
7 7
     <authors>robin.thoni</authors>
8 8
     <owners>robin.thoni</owners>

+ 12
- 0
CacheControl/DBO/DbOutputCacheDbo.cs 파일 보기

@@ -0,0 +1,12 @@
1
+using System;
2
+using System.Data.Entity;
3
+
4
+namespace CacheControl.DBO
5
+{
6
+    public class DbOutputCacheDbo<T> where T : class
7
+    {
8
+        public Func<DbContext> GetDb { get; set; }
9
+
10
+        public Func<DbContext, DbSet<T>> GetTable { get; set; }
11
+    }
12
+}

+ 30
- 0
CacheControl/DataAccess/CacheEntities.Context.cs 파일 보기

@@ -0,0 +1,30 @@
1
+//------------------------------------------------------------------------------
2
+// <auto-generated>
3
+//     This code was generated from a template.
4
+//
5
+//     Manual changes to this file may cause unexpected behavior in your application.
6
+//     Manual changes to this file will be overwritten if the code is regenerated.
7
+// </auto-generated>
8
+//------------------------------------------------------------------------------
9
+
10
+namespace CacheControl.DataAccess
11
+{
12
+    using System;
13
+    using System.Data.Entity;
14
+    using System.Data.Entity.Infrastructure;
15
+    
16
+    public partial class CacheControlEntities : DbContext
17
+    {
18
+        public CacheControlEntities()
19
+            : base("name=CacheControlEntities")
20
+        {
21
+        }
22
+    
23
+        protected override void OnModelCreating(DbModelBuilder modelBuilder)
24
+        {
25
+            throw new UnintentionalCodeFirstException();
26
+        }
27
+    
28
+        public virtual DbSet<T_Cache> T_Cache { get; set; }
29
+    }
30
+}

+ 636
- 0
CacheControl/DataAccess/CacheEntities.Context.tt 파일 보기

@@ -0,0 +1,636 @@
1
+<#@ template language="C#" debug="false" hostspecific="true"#>
2
+<#@ include file="EF6.Utility.CS.ttinclude"#><#@
3
+ output extension=".cs"#><#
4
+
5
+const string inputFile = @"CacheEntities.edmx";
6
+var textTransform = DynamicTextTransformation.Create(this);
7
+var code = new CodeGenerationTools(this);
8
+var ef = new MetadataTools(this);
9
+var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
10
+var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
11
+var itemCollection = loader.CreateEdmItemCollection(inputFile);
12
+var modelNamespace = loader.GetModelNamespace(inputFile);
13
+var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
14
+
15
+var container = itemCollection.OfType<EntityContainer>().FirstOrDefault();
16
+if (container == null)
17
+{
18
+    return string.Empty;
19
+}
20
+#>
21
+//------------------------------------------------------------------------------
22
+// <auto-generated>
23
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
24
+//
25
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
26
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
27
+// </auto-generated>
28
+//------------------------------------------------------------------------------
29
+
30
+<#
31
+
32
+var codeNamespace = code.VsNamespaceSuggestion();
33
+if (!String.IsNullOrEmpty(codeNamespace))
34
+{
35
+#>
36
+namespace <#=code.EscapeNamespace(codeNamespace)#>
37
+{
38
+<#
39
+    PushIndent("    ");
40
+}
41
+
42
+#>
43
+using System;
44
+using System.Data.Entity;
45
+using System.Data.Entity.Infrastructure;
46
+<#
47
+if (container.FunctionImports.Any())
48
+{
49
+#>
50
+using System.Data.Entity.Core.Objects;
51
+using System.Linq;
52
+<#
53
+}
54
+#>
55
+
56
+<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
57
+{
58
+    public <#=code.Escape(container)#>()
59
+        : base("name=<#=container.Name#>")
60
+    {
61
+<#
62
+if (!loader.IsLazyLoadingEnabled(container))
63
+{
64
+#>
65
+        this.Configuration.LazyLoadingEnabled = false;
66
+<#
67
+}
68
+
69
+foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
70
+{
71
+    // Note: the DbSet members are defined below such that the getter and
72
+    // setter always have the same accessibility as the DbSet definition
73
+    if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
74
+    {
75
+#>
76
+        <#=codeStringGenerator.DbSetInitializer(entitySet)#>
77
+<#
78
+    }
79
+}
80
+#>
81
+    }
82
+
83
+    protected override void OnModelCreating(DbModelBuilder modelBuilder)
84
+    {
85
+        throw new UnintentionalCodeFirstException();
86
+    }
87
+
88
+<#
89
+    foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
90
+    {
91
+#>
92
+    <#=codeStringGenerator.DbSet(entitySet)#>
93
+<#
94
+    }
95
+
96
+    foreach (var edmFunction in container.FunctionImports)
97
+    {
98
+        WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
99
+    }
100
+#>
101
+}
102
+<#
103
+
104
+if (!String.IsNullOrEmpty(codeNamespace))
105
+{
106
+    PopIndent();
107
+#>
108
+}
109
+<#
110
+}
111
+#>
112
+<#+
113
+
114
+private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
115
+{
116
+    if (typeMapper.IsComposable(edmFunction))
117
+    {
118
+#>
119
+
120
+    [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
121
+    <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
122
+    {
123
+<#+
124
+        codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
125
+#>
126
+        <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
127
+    }
128
+<#+
129
+    }
130
+    else
131
+    {
132
+#>
133
+
134
+    <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
135
+    {
136
+<#+
137
+        codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
138
+#>
139
+        <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
140
+    }
141
+<#+
142
+        if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
143
+        {
144
+            WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
145
+        }
146
+    }
147
+}
148
+
149
+public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
150
+{
151
+#>
152
+        var <#=name#> = <#=isNotNull#> ?
153
+            <#=notNullInit#> :
154
+            <#=nullInit#>;
155
+
156
+<#+
157
+}
158
+
159
+public const string TemplateId = "CSharp_DbContext_Context_EF6";
160
+
161
+public class CodeStringGenerator
162
+{
163
+    private readonly CodeGenerationTools _code;
164
+    private readonly TypeMapper _typeMapper;
165
+    private readonly MetadataTools _ef;
166
+
167
+    public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
168
+    {
169
+        ArgumentNotNull(code, "code");
170
+        ArgumentNotNull(typeMapper, "typeMapper");
171
+        ArgumentNotNull(ef, "ef");
172
+
173
+        _code = code;
174
+        _typeMapper = typeMapper;
175
+        _ef = ef;
176
+    }
177
+
178
+    public string Property(EdmProperty edmProperty)
179
+    {
180
+        return string.Format(
181
+            CultureInfo.InvariantCulture,
182
+            "{0} {1} {2} {{ {3}get; {4}set; }}",
183
+            Accessibility.ForProperty(edmProperty),
184
+            _typeMapper.GetTypeName(edmProperty.TypeUsage),
185
+            _code.Escape(edmProperty),
186
+            _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
187
+            _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
188
+    }
189
+
190
+    public string NavigationProperty(NavigationProperty navProp)
191
+    {
192
+        var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
193
+        return string.Format(
194
+            CultureInfo.InvariantCulture,
195
+            "{0} {1} {2} {{ {3}get; {4}set; }}",
196
+            AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
197
+            navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
198
+            _code.Escape(navProp),
199
+            _code.SpaceAfter(Accessibility.ForGetter(navProp)),
200
+            _code.SpaceAfter(Accessibility.ForSetter(navProp)));
201
+    }
202
+    
203
+    public string AccessibilityAndVirtual(string accessibility)
204
+    {
205
+        return accessibility + (accessibility != "private" ? " virtual" : "");
206
+    }
207
+    
208
+    public string EntityClassOpening(EntityType entity)
209
+    {
210
+        return string.Format(
211
+            CultureInfo.InvariantCulture,
212
+            "{0} {1}partial class {2}{3}",
213
+            Accessibility.ForType(entity),
214
+            _code.SpaceAfter(_code.AbstractOption(entity)),
215
+            _code.Escape(entity),
216
+            _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
217
+    }
218
+    
219
+    public string EnumOpening(SimpleType enumType)
220
+    {
221
+        return string.Format(
222
+            CultureInfo.InvariantCulture,
223
+            "{0} enum {1} : {2}",
224
+            Accessibility.ForType(enumType),
225
+            _code.Escape(enumType),
226
+            _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
227
+        }
228
+    
229
+    public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
230
+    {
231
+        var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
232
+        foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
233
+        {
234
+            var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
235
+            var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
236
+            var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
237
+            writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
238
+        }
239
+    }
240
+    
241
+    public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
242
+    {
243
+        var parameters = _typeMapper.GetParameters(edmFunction);
244
+        
245
+        return string.Format(
246
+            CultureInfo.InvariantCulture,
247
+            "{0} IQueryable<{1}> {2}({3})",
248
+            AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
249
+            _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
250
+            _code.Escape(edmFunction),
251
+            string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
252
+    }
253
+    
254
+    public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
255
+    {
256
+        var parameters = _typeMapper.GetParameters(edmFunction);
257
+        
258
+        return string.Format(
259
+            CultureInfo.InvariantCulture,
260
+            "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
261
+            _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
262
+            edmFunction.NamespaceName,
263
+            edmFunction.Name,
264
+            string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
265
+            _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
266
+    }
267
+    
268
+    public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
269
+    {
270
+        var parameters = _typeMapper.GetParameters(edmFunction);
271
+        var returnType = _typeMapper.GetReturnType(edmFunction);
272
+
273
+        var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
274
+        if (includeMergeOption)
275
+        {
276
+            paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
277
+        }
278
+
279
+        return string.Format(
280
+            CultureInfo.InvariantCulture,
281
+            "{0} {1} {2}({3})",
282
+            AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
283
+            returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
284
+            _code.Escape(edmFunction),
285
+            paramList);
286
+    }
287
+    
288
+    public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
289
+    {
290
+        var parameters = _typeMapper.GetParameters(edmFunction);
291
+        var returnType = _typeMapper.GetReturnType(edmFunction);
292
+
293
+        var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
294
+        if (includeMergeOption)
295
+        {
296
+            callParams = ", mergeOption" + callParams;
297
+        }
298
+        
299
+        return string.Format(
300
+            CultureInfo.InvariantCulture,
301
+            "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
302
+            returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
303
+            edmFunction.Name,
304
+            callParams);
305
+    }
306
+    
307
+    public string DbSet(EntitySet entitySet)
308
+    {
309
+        return string.Format(
310
+            CultureInfo.InvariantCulture,
311
+            "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
312
+            Accessibility.ForReadOnlyProperty(entitySet),
313
+            _typeMapper.GetTypeName(entitySet.ElementType),
314
+            _code.Escape(entitySet));
315
+    }
316
+
317
+    public string DbSetInitializer(EntitySet entitySet)
318
+    {
319
+        return string.Format(
320
+            CultureInfo.InvariantCulture,
321
+            "{0} = Set<{1}>();",
322
+            _code.Escape(entitySet),
323
+            _typeMapper.GetTypeName(entitySet.ElementType));
324
+    }
325
+
326
+    public string UsingDirectives(bool inHeader, bool includeCollections = true)
327
+    {
328
+        return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
329
+            ? string.Format(
330
+                CultureInfo.InvariantCulture,
331
+                "{0}using System;{1}" +
332
+                "{2}",
333
+                inHeader ? Environment.NewLine : "",
334
+                includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
335
+                inHeader ? "" : Environment.NewLine)
336
+            : "";
337
+    }
338
+}
339
+
340
+public class TypeMapper
341
+{
342
+    private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
343
+
344
+    private readonly System.Collections.IList _errors;
345
+    private readonly CodeGenerationTools _code;
346
+    private readonly MetadataTools _ef;
347
+
348
+    public static string FixNamespaces(string typeName)
349
+    {
350
+        return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
351
+    }
352
+
353
+    public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
354
+    {
355
+        ArgumentNotNull(code, "code");
356
+        ArgumentNotNull(ef, "ef");
357
+        ArgumentNotNull(errors, "errors");
358
+
359
+        _code = code;
360
+        _ef = ef;
361
+        _errors = errors;
362
+    }
363
+
364
+    public string GetTypeName(TypeUsage typeUsage)
365
+    {
366
+        return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
367
+    }
368
+
369
+    public string GetTypeName(EdmType edmType)
370
+    {
371
+        return GetTypeName(edmType, isNullable: null, modelNamespace: null);
372
+    }
373
+
374
+    public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
375
+    {
376
+        return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
377
+    }
378
+
379
+    public string GetTypeName(EdmType edmType, string modelNamespace)
380
+    {
381
+        return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
382
+    }
383
+
384
+    public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
385
+    {
386
+        if (edmType == null)
387
+        {
388
+            return null;
389
+        }
390
+
391
+        var collectionType = edmType as CollectionType;
392
+        if (collectionType != null)
393
+        {
394
+            return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
395
+        }
396
+
397
+        var typeName = _code.Escape(edmType.MetadataProperties
398
+                                .Where(p => p.Name == ExternalTypeNameAttributeName)
399
+                                .Select(p => (string)p.Value)
400
+                                .FirstOrDefault())
401
+            ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
402
+                _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
403
+                _code.Escape(edmType));
404
+
405
+        if (edmType is StructuralType)
406
+        {
407
+            return typeName;
408
+        }
409
+
410
+        if (edmType is SimpleType)
411
+        {
412
+            var clrType = UnderlyingClrType(edmType);
413
+            if (!IsEnumType(edmType))
414
+            {
415
+                typeName = _code.Escape(clrType);
416
+            }
417
+
418
+            typeName = FixNamespaces(typeName);
419
+
420
+            return clrType.IsValueType && isNullable == true ?
421
+                String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
422
+                typeName;
423
+        }
424
+
425
+        throw new ArgumentException("edmType");
426
+    }
427
+    
428
+    public Type UnderlyingClrType(EdmType edmType)
429
+    {
430
+        ArgumentNotNull(edmType, "edmType");
431
+
432
+        var primitiveType = edmType as PrimitiveType;
433
+        if (primitiveType != null)
434
+        {
435
+            return primitiveType.ClrEquivalentType;
436
+        }
437
+
438
+        if (IsEnumType(edmType))
439
+        {
440
+            return GetEnumUnderlyingType(edmType).ClrEquivalentType;
441
+        }
442
+
443
+        return typeof(object);
444
+    }
445
+    
446
+    public object GetEnumMemberValue(MetadataItem enumMember)
447
+    {
448
+        ArgumentNotNull(enumMember, "enumMember");
449
+        
450
+        var valueProperty = enumMember.GetType().GetProperty("Value");
451
+        return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
452
+    }
453
+    
454
+    public string GetEnumMemberName(MetadataItem enumMember)
455
+    {
456
+        ArgumentNotNull(enumMember, "enumMember");
457
+        
458
+        var nameProperty = enumMember.GetType().GetProperty("Name");
459
+        return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
460
+    }
461
+
462
+    public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
463
+    {
464
+        ArgumentNotNull(enumType, "enumType");
465
+
466
+        var membersProperty = enumType.GetType().GetProperty("Members");
467
+        return membersProperty != null 
468
+            ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
469
+            : Enumerable.Empty<MetadataItem>();
470
+    }
471
+    
472
+    public bool EnumIsFlags(EdmType enumType)
473
+    {
474
+        ArgumentNotNull(enumType, "enumType");
475
+        
476
+        var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
477
+        return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
478
+    }
479
+
480
+    public bool IsEnumType(GlobalItem edmType)
481
+    {
482
+        ArgumentNotNull(edmType, "edmType");
483
+
484
+        return edmType.GetType().Name == "EnumType";
485
+    }
486
+
487
+    public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
488
+    {
489
+        ArgumentNotNull(enumType, "enumType");
490
+
491
+        return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
492
+    }
493
+
494
+    public string CreateLiteral(object value)
495
+    {
496
+        if (value == null || value.GetType() != typeof(TimeSpan))
497
+        {
498
+            return _code.CreateLiteral(value);
499
+        }
500
+
501
+        return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
502
+    }
503
+    
504
+    public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
505
+    {
506
+        ArgumentNotNull(types, "types");
507
+        ArgumentNotNull(sourceFile, "sourceFile");
508
+        
509
+        var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
510
+        if (types.Any(item => !hash.Add(item)))
511
+        {
512
+            _errors.Add(
513
+                new CompilerError(sourceFile, -1, -1, "6023",
514
+                    String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
515
+            return false;
516
+        }
517
+        return true;
518
+    }
519
+    
520
+    public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
521
+    {
522
+        return GetItemsToGenerate<SimpleType>(itemCollection)
523
+            .Where(e => IsEnumType(e));
524
+    }
525
+    
526
+    public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
527
+    {
528
+        return itemCollection
529
+            .OfType<T>()
530
+            .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
531
+            .OrderBy(i => i.Name);
532
+    }
533
+
534
+    public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
535
+    {
536
+        return itemCollection
537
+            .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
538
+            .Select(g => GetGlobalItemName(g));
539
+    }
540
+
541
+    public string GetGlobalItemName(GlobalItem item)
542
+    {
543
+        if (item is EdmType)
544
+        {
545
+            return ((EdmType)item).Name;
546
+        }
547
+        else
548
+        {
549
+            return ((EntityContainer)item).Name;
550
+        }
551
+    }
552
+
553
+    public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
554
+    {
555
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
556
+    }
557
+    
558
+    public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
559
+    {
560
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
561
+    }
562
+    
563
+    public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
564
+    {
565
+        return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
566
+    }
567
+    
568
+    public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
569
+    {
570
+        return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
571
+    }
572
+
573
+    public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
574
+    {
575
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
576
+    }
577
+    
578
+    public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
579
+    {
580
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
581
+    }
582
+
583
+    public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
584
+    {
585
+        return type.NavigationProperties.Where(np => np.DeclaringType == type);
586
+    }
587
+    
588
+    public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
589
+    {
590
+        return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
591
+    }
592
+    
593
+    public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
594
+    {
595
+        ArgumentNotNull(edmFunction, "edmFunction");
596
+
597
+        var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
598
+        return returnParamsProperty == null
599
+            ? edmFunction.ReturnParameter
600
+            : ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
601
+    }
602
+
603
+    public bool IsComposable(EdmFunction edmFunction)
604
+    {
605
+        ArgumentNotNull(edmFunction, "edmFunction");
606
+
607
+        var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
608
+        return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
609
+    }
610
+
611
+    public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
612
+    {
613
+        return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
614
+    }
615
+
616
+    public TypeUsage GetReturnType(EdmFunction edmFunction)
617
+    {
618
+        var returnParam = GetReturnParameter(edmFunction);
619
+        return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
620
+    }
621
+    
622
+    public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
623
+    {
624
+        var returnType = GetReturnType(edmFunction);
625
+        return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
626
+    }
627
+}
628
+
629
+public static void ArgumentNotNull<T>(T arg, string name) where T : class
630
+{
631
+    if (arg == null)
632
+    {
633
+        throw new ArgumentNullException(name);
634
+    }
635
+}
636
+#>

+ 10
- 0
CacheControl/DataAccess/CacheEntities.Designer.cs 파일 보기

@@ -0,0 +1,10 @@
1
+// T4 code generation is enabled for model 'C:\Users\robin.thoni\Documents\nuget-3ie\CacheControl\DataAccess\CacheEntities.edmx'. 
2
+// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
3
+// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
4
+// is open in the designer.
5
+
6
+// If no context and entity classes have been generated, it may be because you created an empty model but
7
+// have not yet chosen which version of Entity Framework to use. To generate a context class and entity
8
+// classes for your model, open the model in the designer, right-click on the designer surface, and
9
+// select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
10
+// Item...'.

+ 9
- 0
CacheControl/DataAccess/CacheEntities.cs 파일 보기

@@ -0,0 +1,9 @@
1
+//------------------------------------------------------------------------------
2
+// <auto-generated>
3
+//     This code was generated from a template.
4
+//
5
+//     Manual changes to this file may cause unexpected behavior in your application.
6
+//     Manual changes to this file will be overwritten if the code is regenerated.
7
+// </auto-generated>
8
+//------------------------------------------------------------------------------
9
+

+ 81
- 0
CacheControl/DataAccess/CacheEntities.edmx 파일 보기

@@ -0,0 +1,81 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
3
+  <!-- EF Runtime content -->
4
+  <edmx:Runtime>
5
+    <!-- SSDL content -->
6
+    <edmx:StorageModels>
7
+    <Schema Namespace="CacheControlModel.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2012" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
8
+        <EntityType Name="T_Cache">
9
+          <Key>
10
+            <PropertyRef Name="id" />
11
+          </Key>
12
+          <Property Name="id" Type="bigint" StoreGeneratedPattern="Identity" Nullable="false" />
13
+          <Property Name="cachekey" Type="nvarchar(max)" Nullable="false" />
14
+          <Property Name="content_type" Type="nvarchar" MaxLength="50" Nullable="false" />
15
+          <Property Name="content" Type="varbinary(max)" Nullable="false" />
16
+          <Property Name="etag" Type="nvarchar" MaxLength="50" Nullable="false" />
17
+          <Property Name="date" Type="datetime" Nullable="false" />
18
+        </EntityType>
19
+        <EntityContainer Name="CacheControlModelStoreContainer">
20
+          <EntitySet Name="T_Cache" EntityType="Self.T_Cache" Schema="dbo" store:Type="Tables" />
21
+        </EntityContainer>
22
+      </Schema></edmx:StorageModels>
23
+    <!-- CSDL content -->
24
+    <edmx:ConceptualModels>
25
+      <Schema Namespace="CacheControlModel" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
26
+        <EntityContainer Name="CacheControlEntities" annotation:LazyLoadingEnabled="true">
27
+          <EntitySet Name="T_Cache" EntityType="CacheControlModel.T_Cache" />
28
+        </EntityContainer>
29
+        <EntityType Name="T_Cache">
30
+          <Key>
31
+            <PropertyRef Name="id" />
32
+          </Key>
33
+          <Property Name="id" Type="Int64" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
34
+          <Property Name="cachekey" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
35
+          <Property Name="content_type" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
36
+          <Property Name="content" Type="Binary" Nullable="false" MaxLength="Max" FixedLength="false" />
37
+          <Property Name="etag" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
38
+          <Property Name="date" Type="DateTime" Nullable="false" Precision="3" />
39
+        </EntityType>
40
+      </Schema>
41
+    </edmx:ConceptualModels>
42
+    <!-- C-S mapping content -->
43
+    <edmx:Mappings>
44
+      <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
45
+        <EntityContainerMapping StorageEntityContainer="CacheControlModelStoreContainer" CdmEntityContainer="CacheControlEntities">
46
+          <EntitySetMapping Name="T_Cache">
47
+            <EntityTypeMapping TypeName="CacheControlModel.T_Cache">
48
+              <MappingFragment StoreEntitySet="T_Cache">
49
+                <ScalarProperty Name="date" ColumnName="date" />
50
+                <ScalarProperty Name="etag" ColumnName="etag" />
51
+                <ScalarProperty Name="content" ColumnName="content" />
52
+                <ScalarProperty Name="content_type" ColumnName="content_type" />
53
+                <ScalarProperty Name="cachekey" ColumnName="cachekey" />
54
+                <ScalarProperty Name="id" ColumnName="id" />
55
+              </MappingFragment>
56
+            </EntityTypeMapping>
57
+          </EntitySetMapping>
58
+        </EntityContainerMapping>
59
+      </Mapping>
60
+    </edmx:Mappings>
61
+  </edmx:Runtime>
62
+  <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
63
+  <Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
64
+    <Connection>
65
+      <DesignerInfoPropertySet>
66
+        <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
67
+      </DesignerInfoPropertySet>
68
+    </Connection>
69
+    <Options>
70
+      <DesignerInfoPropertySet>
71
+        <DesignerProperty Name="ValidateOnBuild" Value="true" />
72
+        <DesignerProperty Name="EnablePluralization" Value="false" />
73
+        <DesignerProperty Name="IncludeForeignKeysInModel" Value="true" />
74
+        <DesignerProperty Name="UseLegacyProvider" Value="false" />
75
+        <DesignerProperty Name="CodeGenerationStrategy" Value="None" />
76
+      </DesignerInfoPropertySet>
77
+    </Options>
78
+    <!-- Diagram content (shape and connector positions) -->
79
+    <Diagrams></Diagrams>
80
+  </Designer>
81
+</edmx:Edmx>

+ 12
- 0
CacheControl/DataAccess/CacheEntities.edmx.diagram 파일 보기

@@ -0,0 +1,12 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
3
+ <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
4
+  <edmx:Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
5
+    <!-- Diagram content (shape and connector positions) -->
6
+    <edmx:Diagrams>
7
+      <Diagram DiagramId="69d57a0abfb24604877ae7550c2cf30e" Name="Diagram1">
8
+        <EntityTypeShape EntityType="CacheControlModel.T_Cache" Width="1.5" PointX="0.75" PointY="0.75" />
9
+      </Diagram>
10
+    </edmx:Diagrams>
11
+  </edmx:Designer>
12
+</edmx:Edmx>

+ 726
- 0
CacheControl/DataAccess/CacheEntities.tt 파일 보기

@@ -0,0 +1,726 @@
1
+<#@ template language="C#" debug="false" hostspecific="true"#>
2
+<#@ include file="EF6.Utility.CS.ttinclude"#><#@ 
3
+ output extension=".cs"#><#
4
+
5
+const string inputFile = @"CacheEntities.edmx";
6
+var textTransform = DynamicTextTransformation.Create(this);
7
+var code = new CodeGenerationTools(this);
8
+var ef = new MetadataTools(this);
9
+var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
10
+var	fileManager = EntityFrameworkTemplateFileManager.Create(this);
11
+var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
12
+var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
13
+
14
+if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
15
+{
16
+    return string.Empty;
17
+}
18
+
19
+WriteHeader(codeStringGenerator, fileManager);
20
+
21
+foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
22
+{
23
+    fileManager.StartNewFile(entity.Name + ".cs");
24
+    BeginNamespace(code);
25
+#>
26
+<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
27
+<#=codeStringGenerator.EntityClassOpening(entity)#>
28
+{
29
+<#
30
+    var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
31
+    var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
32
+    var complexProperties = typeMapper.GetComplexProperties(entity);
33
+
34
+    if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
35
+    {
36
+#>
37
+    public <#=code.Escape(entity)#>()
38
+    {
39
+<#
40
+        foreach (var edmProperty in propertiesWithDefaultValues)
41
+        {
42
+#>
43
+        this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
44
+<#
45
+        }
46
+
47
+        foreach (var navigationProperty in collectionNavigationProperties)
48
+        {
49
+#>
50
+        this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
51
+<#
52
+        }
53
+
54
+        foreach (var complexProperty in complexProperties)
55
+        {
56
+#>
57
+        this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
58
+<#
59
+        }
60
+#>
61
+    }
62
+
63
+<#
64
+    }
65
+
66
+    var simpleProperties = typeMapper.GetSimpleProperties(entity);
67
+    if (simpleProperties.Any())
68
+    {
69
+        foreach (var edmProperty in simpleProperties)
70
+        {
71
+#>
72
+    <#=codeStringGenerator.Property(edmProperty)#>
73
+<#
74
+        }
75
+    }
76
+
77
+    if (complexProperties.Any())
78
+    {
79
+#>
80
+
81
+<#
82
+        foreach(var complexProperty in complexProperties)
83
+        {
84
+#>
85
+    <#=codeStringGenerator.Property(complexProperty)#>
86
+<#
87
+        }
88
+    }
89
+
90
+    var navigationProperties = typeMapper.GetNavigationProperties(entity);
91
+    if (navigationProperties.Any())
92
+    {
93
+#>
94
+
95
+<#
96
+        foreach (var navigationProperty in navigationProperties)
97
+        {
98
+#>
99
+    <#=codeStringGenerator.NavigationProperty(navigationProperty)#>
100
+<#
101
+        }
102
+    }
103
+#>
104
+}
105
+<#
106
+    EndNamespace(code);
107
+}
108
+
109
+foreach (var complex in typeMapper.GetItemsToGenerate<ComplexType>(itemCollection))
110
+{
111
+    fileManager.StartNewFile(complex.Name + ".cs");
112
+    BeginNamespace(code);
113
+#>
114
+<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
115
+<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
116
+{
117
+<#
118
+    var complexProperties = typeMapper.GetComplexProperties(complex);
119
+    var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
120
+
121
+    if (propertiesWithDefaultValues.Any() || complexProperties.Any())
122
+    {
123
+#>
124
+    public <#=code.Escape(complex)#>()
125
+    {
126
+<#
127
+        foreach (var edmProperty in propertiesWithDefaultValues)
128
+        {
129
+#>
130
+        this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
131
+<#
132
+        }
133
+
134
+        foreach (var complexProperty in complexProperties)
135
+        {
136
+#>
137
+        this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
138
+<#
139
+        }
140
+#>
141
+    }
142
+
143
+<#
144
+    }
145
+
146
+    var simpleProperties = typeMapper.GetSimpleProperties(complex);
147
+    if (simpleProperties.Any())
148
+    {
149
+        foreach(var edmProperty in simpleProperties)
150
+        {
151
+#>
152
+    <#=codeStringGenerator.Property(edmProperty)#>
153
+<#
154
+        }
155
+    }
156
+
157
+    if (complexProperties.Any())
158
+    {
159
+#>
160
+
161
+<#
162
+        foreach(var edmProperty in complexProperties)
163
+        {
164
+#>
165
+    <#=codeStringGenerator.Property(edmProperty)#>
166
+<#
167
+        }
168
+    }
169
+#>
170
+}
171
+<#
172
+    EndNamespace(code);
173
+}
174
+
175
+foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
176
+{
177
+    fileManager.StartNewFile(enumType.Name + ".cs");
178
+    BeginNamespace(code);
179
+#>
180
+<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
181
+<#
182
+    if (typeMapper.EnumIsFlags(enumType))
183
+    {
184
+#>
185
+[Flags]
186
+<#
187
+    }
188
+#>
189
+<#=codeStringGenerator.EnumOpening(enumType)#>
190
+{
191
+<#
192
+    var foundOne = false;
193
+    
194
+    foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
195
+    {
196
+        foundOne = true;
197
+#>
198
+    <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
199
+<#
200
+    }
201
+
202
+    if (foundOne)
203
+    {
204
+        this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
205
+    }
206
+#>
207
+}
208
+<#
209
+    EndNamespace(code);
210
+}
211
+
212
+fileManager.Process();
213
+
214
+#>
215
+<#+
216
+
217
+public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
218
+{
219
+    fileManager.StartHeader();
220
+#>
221
+//------------------------------------------------------------------------------
222
+// <auto-generated>
223
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
224
+//
225
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
226
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
227
+// </auto-generated>
228
+//------------------------------------------------------------------------------
229
+<#=codeStringGenerator.UsingDirectives(inHeader: true)#>
230
+<#+
231
+    fileManager.EndBlock();
232
+}
233
+
234
+public void BeginNamespace(CodeGenerationTools code)
235
+{
236
+    var codeNamespace = code.VsNamespaceSuggestion();
237
+    if (!String.IsNullOrEmpty(codeNamespace))
238
+    {
239
+#>
240
+namespace <#=code.EscapeNamespace(codeNamespace)#>
241
+{
242
+<#+
243
+        PushIndent("    ");
244
+    }
245
+}
246
+
247
+public void EndNamespace(CodeGenerationTools code)
248
+{
249
+    if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
250
+    {
251
+        PopIndent();
252
+#>
253
+}
254
+<#+
255
+    }
256
+}
257
+
258
+public const string TemplateId = "CSharp_DbContext_Types_EF6";
259
+
260
+public class CodeStringGenerator
261
+{
262
+    private readonly CodeGenerationTools _code;
263
+    private readonly TypeMapper _typeMapper;
264
+    private readonly MetadataTools _ef;
265
+
266
+    public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
267
+    {
268
+        ArgumentNotNull(code, "code");
269
+        ArgumentNotNull(typeMapper, "typeMapper");
270
+        ArgumentNotNull(ef, "ef");
271
+
272
+        _code = code;
273
+        _typeMapper = typeMapper;
274
+        _ef = ef;
275
+    }
276
+
277
+    public string Property(EdmProperty edmProperty)
278
+    {
279
+        return string.Format(
280
+            CultureInfo.InvariantCulture,
281
+            "{0} {1} {2} {{ {3}get; {4}set; }}",
282
+            Accessibility.ForProperty(edmProperty),
283
+            _typeMapper.GetTypeName(edmProperty.TypeUsage),
284
+            _code.Escape(edmProperty),
285
+            _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
286
+            _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
287
+    }
288
+
289
+    public string NavigationProperty(NavigationProperty navProp)
290
+    {
291
+        var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
292
+        return string.Format(
293
+            CultureInfo.InvariantCulture,
294
+            "{0} {1} {2} {{ {3}get; {4}set; }}",
295
+            AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
296
+            navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
297
+            _code.Escape(navProp),
298
+            _code.SpaceAfter(Accessibility.ForGetter(navProp)),
299
+            _code.SpaceAfter(Accessibility.ForSetter(navProp)));
300
+    }
301
+    
302
+    public string AccessibilityAndVirtual(string accessibility)
303
+    {
304
+        return accessibility + (accessibility != "private" ? " virtual" : "");
305
+    }
306
+    
307
+    public string EntityClassOpening(EntityType entity)
308
+    {
309
+        return string.Format(
310
+            CultureInfo.InvariantCulture,
311
+            "{0} {1}partial class {2}{3}",
312
+            Accessibility.ForType(entity),
313
+            _code.SpaceAfter(_code.AbstractOption(entity)),
314
+            _code.Escape(entity),
315
+            _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
316
+    }
317
+    
318
+    public string EnumOpening(SimpleType enumType)
319
+    {
320
+        return string.Format(
321
+            CultureInfo.InvariantCulture,
322
+            "{0} enum {1} : {2}",
323
+            Accessibility.ForType(enumType),
324
+            _code.Escape(enumType),
325
+            _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
326
+        }
327
+    
328
+    public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
329
+    {
330
+        var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
331
+        foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
332
+        {
333
+            var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
334
+            var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
335
+            var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
336
+            writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
337
+        }
338
+    }
339
+    
340
+    public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
341
+    {
342
+        var parameters = _typeMapper.GetParameters(edmFunction);
343
+        
344
+        return string.Format(
345
+            CultureInfo.InvariantCulture,
346
+            "{0} IQueryable<{1}> {2}({3})",
347
+            AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
348
+            _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
349
+            _code.Escape(edmFunction),
350
+            string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
351
+    }
352
+    
353
+    public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
354
+    {
355
+        var parameters = _typeMapper.GetParameters(edmFunction);
356
+        
357
+        return string.Format(
358
+            CultureInfo.InvariantCulture,
359
+            "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
360
+            _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
361
+            edmFunction.NamespaceName,
362
+            edmFunction.Name,
363
+            string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
364
+            _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
365
+    }
366
+    
367
+    public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
368
+    {
369
+        var parameters = _typeMapper.GetParameters(edmFunction);
370
+        var returnType = _typeMapper.GetReturnType(edmFunction);
371
+
372
+        var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
373
+        if (includeMergeOption)
374
+        {
375
+            paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
376
+        }
377
+
378
+        return string.Format(
379
+            CultureInfo.InvariantCulture,
380
+            "{0} {1} {2}({3})",
381
+            AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
382
+            returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
383
+            _code.Escape(edmFunction),
384
+            paramList);
385
+    }
386
+    
387
+    public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
388
+    {
389
+        var parameters = _typeMapper.GetParameters(edmFunction);
390
+        var returnType = _typeMapper.GetReturnType(edmFunction);
391
+
392
+        var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
393
+        if (includeMergeOption)
394
+        {
395
+            callParams = ", mergeOption" + callParams;
396
+        }
397
+        
398
+        return string.Format(
399
+            CultureInfo.InvariantCulture,
400
+            "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
401
+            returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
402
+            edmFunction.Name,
403
+            callParams);
404
+    }
405
+    
406
+    public string DbSet(EntitySet entitySet)
407
+    {
408
+        return string.Format(
409
+            CultureInfo.InvariantCulture,
410
+            "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
411
+            Accessibility.ForReadOnlyProperty(entitySet),
412
+            _typeMapper.GetTypeName(entitySet.ElementType),
413
+            _code.Escape(entitySet));
414
+    }
415
+
416
+    public string UsingDirectives(bool inHeader, bool includeCollections = true)
417
+    {
418
+        return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
419
+            ? string.Format(
420
+                CultureInfo.InvariantCulture,
421
+                "{0}using System;{1}" +
422
+                "{2}",
423
+                inHeader ? Environment.NewLine : "",
424
+                includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
425
+                inHeader ? "" : Environment.NewLine)
426
+            : "";
427
+    }
428
+}
429
+
430
+public class TypeMapper
431
+{
432
+    private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
433
+
434
+    private readonly System.Collections.IList _errors;
435
+    private readonly CodeGenerationTools _code;
436
+    private readonly MetadataTools _ef;
437
+
438
+    public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
439
+    {
440
+        ArgumentNotNull(code, "code");
441
+        ArgumentNotNull(ef, "ef");
442
+        ArgumentNotNull(errors, "errors");
443
+
444
+        _code = code;
445
+        _ef = ef;
446
+        _errors = errors;
447
+    }
448
+
449
+    public static string FixNamespaces(string typeName)
450
+    {
451
+        return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
452
+    }
453
+
454
+    public string GetTypeName(TypeUsage typeUsage)
455
+    {
456
+        return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
457
+    }
458
+
459
+    public string GetTypeName(EdmType edmType)
460
+    {
461
+        return GetTypeName(edmType, isNullable: null, modelNamespace: null);
462
+    }
463
+
464
+    public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
465
+    {
466
+        return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
467
+    }
468
+
469
+    public string GetTypeName(EdmType edmType, string modelNamespace)
470
+    {
471
+        return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
472
+    }
473
+
474
+    public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
475
+    {
476
+        if (edmType == null)
477
+        {
478
+            return null;
479
+        }
480
+
481
+        var collectionType = edmType as CollectionType;
482
+        if (collectionType != null)
483
+        {
484
+            return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
485
+        }
486
+
487
+        var typeName = _code.Escape(edmType.MetadataProperties
488
+                                .Where(p => p.Name == ExternalTypeNameAttributeName)
489
+                                .Select(p => (string)p.Value)
490
+                                .FirstOrDefault())
491
+            ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
492
+                _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
493
+                _code.Escape(edmType));
494
+
495
+        if (edmType is StructuralType)
496
+        {
497
+            return typeName;
498
+        }
499
+
500
+        if (edmType is SimpleType)
501
+        {
502
+            var clrType = UnderlyingClrType(edmType);
503
+            if (!IsEnumType(edmType))
504
+            {
505
+                typeName = _code.Escape(clrType);
506
+            }
507
+
508
+            typeName = FixNamespaces(typeName);
509
+
510
+            return clrType.IsValueType && isNullable == true ?
511
+                String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
512
+                typeName;
513
+        }
514
+
515
+        throw new ArgumentException("edmType");
516
+    }
517
+    
518
+    public Type UnderlyingClrType(EdmType edmType)
519
+    {
520
+        ArgumentNotNull(edmType, "edmType");
521
+
522
+        var primitiveType = edmType as PrimitiveType;
523
+        if (primitiveType != null)
524
+        {
525
+            return primitiveType.ClrEquivalentType;
526
+        }
527
+
528
+        if (IsEnumType(edmType))
529
+        {
530
+            return GetEnumUnderlyingType(edmType).ClrEquivalentType;
531
+        }
532
+
533
+        return typeof(object);
534
+    }
535
+    
536
+    public object GetEnumMemberValue(MetadataItem enumMember)
537
+    {
538
+        ArgumentNotNull(enumMember, "enumMember");
539
+        
540
+        var valueProperty = enumMember.GetType().GetProperty("Value");
541
+        return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
542
+    }
543
+    
544
+    public string GetEnumMemberName(MetadataItem enumMember)
545
+    {
546
+        ArgumentNotNull(enumMember, "enumMember");
547
+        
548
+        var nameProperty = enumMember.GetType().GetProperty("Name");
549
+        return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
550
+    }
551
+
552
+    public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
553
+    {
554
+        ArgumentNotNull(enumType, "enumType");
555
+
556
+        var membersProperty = enumType.GetType().GetProperty("Members");
557
+        return membersProperty != null 
558
+            ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
559
+            : Enumerable.Empty<MetadataItem>();
560
+    }
561
+    
562
+    public bool EnumIsFlags(EdmType enumType)
563
+    {
564
+        ArgumentNotNull(enumType, "enumType");
565
+        
566
+        var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
567
+        return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
568
+    }
569
+
570
+    public bool IsEnumType(GlobalItem edmType)
571
+    {
572
+        ArgumentNotNull(edmType, "edmType");
573
+
574
+        return edmType.GetType().Name == "EnumType";
575
+    }
576
+
577
+    public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
578
+    {
579
+        ArgumentNotNull(enumType, "enumType");
580
+
581
+        return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
582
+    }
583
+
584
+    public string CreateLiteral(object value)
585
+    {
586
+        if (value == null || value.GetType() != typeof(TimeSpan))
587
+        {
588
+            return _code.CreateLiteral(value);
589
+        }
590
+
591
+        return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
592
+    }
593
+    
594
+    public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
595
+    {
596
+        ArgumentNotNull(types, "types");
597
+        ArgumentNotNull(sourceFile, "sourceFile");
598
+        
599
+        var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
600
+        if (types.Any(item => !hash.Add(item)))
601
+        {
602
+            _errors.Add(
603
+                new CompilerError(sourceFile, -1, -1, "6023",
604
+                    String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
605
+            return false;
606
+        }
607
+        return true;
608
+    }
609
+    
610
+    public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
611
+    {
612
+        return GetItemsToGenerate<SimpleType>(itemCollection)
613
+            .Where(e => IsEnumType(e));
614
+    }
615
+    
616
+    public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
617
+    {
618
+        return itemCollection
619
+            .OfType<T>()
620
+            .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
621
+            .OrderBy(i => i.Name);
622
+    }
623
+
624
+    public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
625
+    {
626
+        return itemCollection
627
+            .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
628
+            .Select(g => GetGlobalItemName(g));
629
+    }
630
+
631
+    public string GetGlobalItemName(GlobalItem item)
632
+    {
633
+        if (item is EdmType)
634
+        {
635
+            return ((EdmType)item).Name;
636
+        }
637
+        else
638
+        {
639
+            return ((EntityContainer)item).Name;
640
+        }
641
+    }
642
+
643
+    public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
644
+    {
645
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
646
+    }
647
+    
648
+    public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
649
+    {
650
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
651
+    }
652
+    
653
+    public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
654
+    {
655
+        return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
656
+    }
657
+    
658
+    public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
659
+    {
660
+        return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
661
+    }
662
+
663
+    public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
664
+    {
665
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
666
+    }
667
+    
668
+    public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
669
+    {
670
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
671
+    }
672
+
673
+    public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
674
+    {
675
+        return type.NavigationProperties.Where(np => np.DeclaringType == type);
676
+    }
677
+    
678
+    public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
679
+    {
680
+        return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
681
+    }
682
+    
683
+    public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
684
+    {
685
+        ArgumentNotNull(edmFunction, "edmFunction");
686
+
687
+        var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
688
+        return returnParamsProperty == null
689
+            ? edmFunction.ReturnParameter
690
+            : ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
691
+    }
692
+
693
+    public bool IsComposable(EdmFunction edmFunction)
694
+    {
695
+        ArgumentNotNull(edmFunction, "edmFunction");
696
+
697
+        var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
698
+        return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
699
+    }
700
+
701
+    public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
702
+    {
703
+        return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
704
+    }
705
+
706
+    public TypeUsage GetReturnType(EdmFunction edmFunction)
707
+    {
708
+        var returnParam = GetReturnParameter(edmFunction);
709
+        return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
710
+    }
711
+    
712
+    public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
713
+    {
714
+        var returnType = GetReturnType(edmFunction);
715
+        return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
716
+    }
717
+}
718
+
719
+public static void ArgumentNotNull<T>(T arg, string name) where T : class
720
+{
721
+    if (arg == null)
722
+    {
723
+        throw new ArgumentNullException(name);
724
+    }
725
+}
726
+#>

+ 24
- 0
CacheControl/DataAccess/T_Cache.cs 파일 보기

@@ -0,0 +1,24 @@
1
+//------------------------------------------------------------------------------
2
+// <auto-generated>
3
+//     This code was generated from a template.
4
+//
5
+//     Manual changes to this file may cause unexpected behavior in your application.
6
+//     Manual changes to this file will be overwritten if the code is regenerated.
7
+// </auto-generated>
8
+//------------------------------------------------------------------------------
9
+
10
+namespace CacheControl.DataAccess
11
+{
12
+    using System;
13
+    using System.Collections.Generic;
14
+    
15
+    public partial class T_Cache
16
+    {
17
+        public long id { get; set; }
18
+        public string cachekey { get; set; }
19
+        public string content_type { get; set; }
20
+        public byte[] content { get; set; }
21
+        public string etag { get; set; }
22
+        public System.DateTime date { get; set; }
23
+    }
24
+}

+ 25
- 0
CacheControl/DataAccess/schema.txt 파일 보기

@@ -0,0 +1,25 @@
1
+USE [CacheControl]
2
+GO
3
+/****** Object:  Table [dbo].[T_Cache]    Script Date: 11/06/2015 20:45:27 ******/
4
+SET ANSI_NULLS ON
5
+GO
6
+SET QUOTED_IDENTIFIER ON
7
+GO
8
+SET ANSI_PADDING ON
9
+GO
10
+CREATE TABLE [dbo].[T_Cache](
11
+	[id] [bigint] IDENTITY(1,1) NOT NULL,
12
+	[cachekey] [nvarchar](max) NOT NULL,
13
+	[content_type] [nvarchar](50) NOT NULL,
14
+	[content] [varbinary](max) NOT NULL,
15
+	[etag] [nvarchar](50) NOT NULL,
16
+	[date] [datetime] NOT NULL,
17
+ CONSTRAINT [PK_T_Cache] PRIMARY KEY CLUSTERED 
18
+(
19
+	[id] ASC
20
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
21
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
22
+
23
+GO
24
+SET ANSI_PADDING OFF
25
+GO

+ 1
- 0
CacheControl/packages.config 파일 보기

@@ -1,5 +1,6 @@
1 1
 <?xml version="1.0" encoding="utf-8"?>
2 2
 <packages>
3
+  <package id="EntityFramework" version="6.1.3" targetFramework="net45" />
3 4
   <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net45" />
4 5
   <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
5 6
   <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />

Loading…
취소
저장