├── .gitignore ├── DataManager.sln ├── DataManager ├── App.config ├── Common │ ├── AggregateExceptionBuilder.cs │ ├── Cleaner.cs │ ├── ConnectionParameters.cs │ ├── ContextMap.cs │ ├── ContextProviderCreator.cs │ ├── Countable.cs │ ├── ExecutionPolicy.cs │ ├── Konstants.cs │ ├── QuickLock.cs │ ├── SandBox.cs │ ├── SharedData.cs │ ├── ThreadRest.cs │ └── ThreadsMap.cs ├── ContextConsumers │ ├── ContextConsumerBase.cs │ ├── EntityReader.cs │ ├── EntityReaderWriter.cs │ ├── EntityWriter.cs │ └── SqlDirect.cs ├── ContextProviders │ ├── ContextProviderBase.cs │ ├── ContextProviderWithAge.cs │ ├── LegacyProvider.cs │ └── SimpleContextProvider.cs ├── DataManager.csproj ├── DataManager.snk ├── DataManagers │ ├── DataManagerWithPolicy.cs │ └── LegacyDataManager.cs ├── Interfaces │ ├── ICleaner.cs │ ├── IContextMap.cs │ ├── IDataManager.cs │ ├── IDataRepository.cs │ ├── IDataRepositoryProvider.cs │ ├── ISqlDirect.cs │ └── Interfaces.cs ├── Properties │ └── AssemblyInfo.cs ├── Strategy │ ├── CleaningStrategy.cs │ ├── RemoveLeastRecentlyUsed.cs │ ├── RemoveOnlyWhenThreadIsDead.cs │ └── RemoveUnused.cs ├── bin │ ├── Debug │ │ ├── EntityFramework.SqlServer.xml │ │ └── EntityFramework.xml │ └── Release │ │ └── EntityFramework.xml └── packages.config ├── LICENSE ├── README.md ├── Samples ├── My First App │ ├── My First App.csproj │ └── Program.cs ├── Polly and Molly │ ├── Polly and Molly.csproj │ └── Program.cs ├── Sample Database Script.sql └── Sample.Entities │ ├── App.Config │ ├── Department.cs │ ├── Employee.cs │ ├── Entities.Designer.cs │ ├── Entities.cs │ ├── Entities.edmx │ ├── Entities.edmx.diagram │ ├── Entities.tt │ ├── Properties │ └── AssemblyInfo.cs │ ├── Sample.Entities.csproj │ └── packages.config ├── UnitTests ├── App.config ├── Employee.cs ├── Entities.Context.cs ├── Entities.Context.tt ├── Entities.Designer.cs ├── Entities.cs ├── Entities.edmx ├── Entities.edmx.diagram ├── Entities.tt ├── InitializeDatabase.sql ├── Person.cs ├── PolicyManager.cs ├── Properties │ └── AssemblyInfo.cs ├── TestBase.cs ├── UnitTests.csproj ├── bin │ ├── Debug │ │ ├── EntityFramework.SqlServer.xml │ │ ├── EntityFramework.xml │ │ └── UnitTests.dll.config │ └── Release │ │ ├── EntityFramework.SqlServer.xml │ │ ├── EntityFramework.xml │ │ └── UnitTests.dll.config └── packages.config └── packages ├── EntityFramework.4.3.1 ├── Content │ ├── App.config.transform │ └── Web.config.transform ├── EntityFramework.4.3.1.nupkg ├── lib │ └── net40 │ │ └── EntityFramework.xml └── tools │ ├── EF4.3on.NET4.5Readme.txt │ ├── EntityFramework.psd1 │ ├── EntityFramework.psm1 │ ├── init.ps1 │ └── install.ps1 ├── EntityFramework.5.0.0 ├── Content │ ├── App.config.transform │ └── Web.config.transform ├── EntityFramework.5.0.0.nupkg ├── lib │ ├── net40 │ │ └── EntityFramework.xml │ └── net45 │ │ └── EntityFramework.xml └── tools │ ├── EntityFramework.PS3.psd1 │ ├── EntityFramework.psd1 │ ├── EntityFramework.psm1 │ ├── Redirect.VS11.config │ ├── Redirect.config │ ├── about_EntityFramework.help.txt │ ├── init.ps1 │ └── install.ps1 └── EntityFramework.6.1.3 ├── EntityFramework.6.1.3.nupkg └── lib └── net45 └── EntityFramework.SqlServer.xml /.gitignore: -------------------------------------------------------------------------------- 1 | [Oo]bj/ 2 | [Bb]in/ 3 | TestResults/ 4 | .nuget/ 5 | _ReSharper.*/ 6 | [Pp]ackages/ 7 | artifacts/ 8 | PublishProfiles/ 9 | .vscode/ 10 | *.user 11 | *.suo 12 | *.cache 13 | *.docstates 14 | _ReSharper.* 15 | nuget.exe 16 | *net45.csproj 17 | *net451.csproj 18 | *k10.csproj 19 | *.psess 20 | *.vsp 21 | *.pidb 22 | *.userprefs 23 | *DS_Store 24 | *.ncrunchsolution 25 | *.*sdf 26 | *.ipch 27 | *.sln.ide 28 | *.lock.json 29 | *.db 30 | .vs/ 31 | config.test.json 32 | *.log 33 | /.build/ 34 | .testPublish/ 35 | .idea/ 36 | *.sln.iml 37 | *.DotSettings 38 | .idea.* 39 | *.obj 40 | *.exe 41 | *.pdb 42 | *.user 43 | *.aps 44 | *.pch 45 | *.vspscc 46 | *_i.c 47 | *_p.c 48 | *.ncb 49 | *.suo 50 | *.tlb 51 | *.tlh 52 | *.bak 53 | *.cache 54 | *.ilk 55 | *.log 56 | *.dll 57 | *.lib 58 | *.sbr -------------------------------------------------------------------------------- /DataManager.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataManager", "DataManager\DataManager.csproj", "{1279A4CA-914A-4899-91CA-07B36915CC8D}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{7B582A27-12BE-4963-9038-A522D29550DA}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "My First App", "Samples\My First App\My First App.csproj", "{E56E741B-E75E-4ED5-9D61-E45BEE60314F}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Entities", "Samples\Sample.Entities\Sample.Entities.csproj", "{FAEA2539-5184-49C7-A8B3-13065D0F426D}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Polly and Molly", "Samples\Polly and Molly\Polly and Molly.csproj", "{443115D1-2451-46FA-9493-B0B874529CA7}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Debug|ARM = Debug|ARM 22 | Debug|x64 = Debug|x64 23 | Debug|x86 = Debug|x86 24 | Release|Any CPU = Release|Any CPU 25 | Release|ARM = Release|ARM 26 | Release|x64 = Release|x64 27 | Release|x86 = Release|x86 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Debug|ARM.ActiveCfg = Debug|Any CPU 33 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Debug|ARM.Build.0 = Debug|Any CPU 34 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Debug|x64.ActiveCfg = Debug|Any CPU 35 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Debug|x64.Build.0 = Debug|Any CPU 36 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Debug|x86.ActiveCfg = Debug|Any CPU 37 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Debug|x86.Build.0 = Debug|Any CPU 38 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Release|ARM.ActiveCfg = Release|Any CPU 41 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Release|ARM.Build.0 = Release|Any CPU 42 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Release|x64.ActiveCfg = Release|Any CPU 43 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Release|x64.Build.0 = Release|Any CPU 44 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Release|x86.ActiveCfg = Release|Any CPU 45 | {1279A4CA-914A-4899-91CA-07B36915CC8D}.Release|x86.Build.0 = Release|Any CPU 46 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Debug|ARM.ActiveCfg = Debug|Any CPU 49 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Debug|ARM.Build.0 = Debug|Any CPU 50 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Debug|x64.ActiveCfg = Debug|Any CPU 51 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Debug|x64.Build.0 = Debug|Any CPU 52 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Debug|x86.ActiveCfg = Debug|Any CPU 53 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Debug|x86.Build.0 = Debug|Any CPU 54 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Release|ARM.ActiveCfg = Release|Any CPU 57 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Release|ARM.Build.0 = Release|Any CPU 58 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Release|x64.ActiveCfg = Release|Any CPU 59 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Release|x64.Build.0 = Release|Any CPU 60 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Release|x86.ActiveCfg = Release|Any CPU 61 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9}.Release|x86.Build.0 = Release|Any CPU 62 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 63 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Debug|Any CPU.Build.0 = Debug|Any CPU 64 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Debug|ARM.ActiveCfg = Debug|Any CPU 65 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Debug|ARM.Build.0 = Debug|Any CPU 66 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Debug|x64.ActiveCfg = Debug|Any CPU 67 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Debug|x64.Build.0 = Debug|Any CPU 68 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Debug|x86.ActiveCfg = Debug|Any CPU 69 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Debug|x86.Build.0 = Debug|Any CPU 70 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Release|Any CPU.ActiveCfg = Release|Any CPU 71 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Release|Any CPU.Build.0 = Release|Any CPU 72 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Release|ARM.ActiveCfg = Release|Any CPU 73 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Release|ARM.Build.0 = Release|Any CPU 74 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Release|x64.ActiveCfg = Release|Any CPU 75 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Release|x64.Build.0 = Release|Any CPU 76 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Release|x86.ActiveCfg = Release|Any CPU 77 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F}.Release|x86.Build.0 = Release|Any CPU 78 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 79 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Debug|Any CPU.Build.0 = Debug|Any CPU 80 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Debug|ARM.ActiveCfg = Debug|Any CPU 81 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Debug|ARM.Build.0 = Debug|Any CPU 82 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Debug|x64.ActiveCfg = Debug|Any CPU 83 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Debug|x64.Build.0 = Debug|Any CPU 84 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Debug|x86.ActiveCfg = Debug|Any CPU 85 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Debug|x86.Build.0 = Debug|Any CPU 86 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Release|Any CPU.ActiveCfg = Release|Any CPU 87 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Release|Any CPU.Build.0 = Release|Any CPU 88 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Release|ARM.ActiveCfg = Release|Any CPU 89 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Release|ARM.Build.0 = Release|Any CPU 90 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Release|x64.ActiveCfg = Release|Any CPU 91 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Release|x64.Build.0 = Release|Any CPU 92 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Release|x86.ActiveCfg = Release|Any CPU 93 | {FAEA2539-5184-49C7-A8B3-13065D0F426D}.Release|x86.Build.0 = Release|Any CPU 94 | {443115D1-2451-46FA-9493-B0B874529CA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 95 | {443115D1-2451-46FA-9493-B0B874529CA7}.Debug|Any CPU.Build.0 = Debug|Any CPU 96 | {443115D1-2451-46FA-9493-B0B874529CA7}.Debug|ARM.ActiveCfg = Debug|Any CPU 97 | {443115D1-2451-46FA-9493-B0B874529CA7}.Debug|ARM.Build.0 = Debug|Any CPU 98 | {443115D1-2451-46FA-9493-B0B874529CA7}.Debug|x64.ActiveCfg = Debug|Any CPU 99 | {443115D1-2451-46FA-9493-B0B874529CA7}.Debug|x64.Build.0 = Debug|Any CPU 100 | {443115D1-2451-46FA-9493-B0B874529CA7}.Debug|x86.ActiveCfg = Debug|Any CPU 101 | {443115D1-2451-46FA-9493-B0B874529CA7}.Debug|x86.Build.0 = Debug|Any CPU 102 | {443115D1-2451-46FA-9493-B0B874529CA7}.Release|Any CPU.ActiveCfg = Release|Any CPU 103 | {443115D1-2451-46FA-9493-B0B874529CA7}.Release|Any CPU.Build.0 = Release|Any CPU 104 | {443115D1-2451-46FA-9493-B0B874529CA7}.Release|ARM.ActiveCfg = Release|Any CPU 105 | {443115D1-2451-46FA-9493-B0B874529CA7}.Release|ARM.Build.0 = Release|Any CPU 106 | {443115D1-2451-46FA-9493-B0B874529CA7}.Release|x64.ActiveCfg = Release|Any CPU 107 | {443115D1-2451-46FA-9493-B0B874529CA7}.Release|x64.Build.0 = Release|Any CPU 108 | {443115D1-2451-46FA-9493-B0B874529CA7}.Release|x86.ActiveCfg = Release|Any CPU 109 | {443115D1-2451-46FA-9493-B0B874529CA7}.Release|x86.Build.0 = Release|Any CPU 110 | EndGlobalSection 111 | GlobalSection(SolutionProperties) = preSolution 112 | HideSolutionNode = FALSE 113 | EndGlobalSection 114 | GlobalSection(NestedProjects) = preSolution 115 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F} = {7B582A27-12BE-4963-9038-A522D29550DA} 116 | {FAEA2539-5184-49C7-A8B3-13065D0F426D} = {7B582A27-12BE-4963-9038-A522D29550DA} 117 | {443115D1-2451-46FA-9493-B0B874529CA7} = {7B582A27-12BE-4963-9038-A522D29550DA} 118 | EndGlobalSection 119 | EndGlobal 120 | -------------------------------------------------------------------------------- /DataManager/App.config: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /DataManager/Common/AggregateExceptionBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericDataManager.Common 8 | { 9 | public class AggregateExceptionBuilder 10 | { 11 | readonly List _errors; 12 | readonly string _message; 13 | 14 | public AggregateExceptionBuilder(string message = "") 15 | { 16 | _message = message; 17 | _errors = new List(); 18 | } 19 | 20 | public bool HasErrors => _errors.Count > 0; 21 | public void Add(Exception ex) => _errors.Add(ex); 22 | public AggregateException ToAggregateException() => string.IsNullOrEmpty(_message) ? new AggregateException(_errors.ToArray()) : new AggregateException(_message, _errors.ToArray()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DataManager/Common/Cleaner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using GenericDataManager.Interfaces; 10 | using GenericDataManager.Strategies; 11 | 12 | namespace GenericDataManager.Common 13 | { 14 | internal class Cleaner: 15 | ICleaner 16 | where TStrategy : CleaningStrategyBase, IDisposable 17 | { 18 | readonly ExecutionPolicy KPolicy; 19 | readonly Tuple _threadArgs; 20 | 21 | readonly ThreadRest _rest; 22 | readonly Thread _cleaner; 23 | 24 | 25 | internal Cleaner(IContextMap map, ExecutionPolicy policy) 26 | { 27 | KPolicy = policy; 28 | _rest = new ThreadRest(KPolicy.HeartBeat); 29 | 30 | _threadArgs = new Tuple(map, policy); 31 | 32 | _cleaner = new Thread(new ParameterizedThreadStart(CleanerLifePath)); 33 | _cleaner.Name = Konstants.CleanerName; 34 | _cleaner.Priority = ThreadPriority.BelowNormal; 35 | _cleaner.IsBackground = true; 36 | } 37 | 38 | 39 | internal void CleanerLifePath(object threadArgs) 40 | { 41 | var args = threadArgs as Tuple; 42 | 43 | BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance; 44 | using (var cleaner = Activator.CreateInstance(typeof(TStrategy), flags, null, new Object[] { args.Item1, args.Item2 }, null) as TStrategy) 45 | { 46 | while (_rest.ShouldContinue) 47 | { 48 | cleaner.Clean(); 49 | _rest.Snooze(); 50 | } 51 | } 52 | } 53 | 54 | void ICleaner.Start() 55 | { 56 | _cleaner.Start(_threadArgs); 57 | } 58 | 59 | 60 | void IDisposable.Dispose() 61 | { 62 | _rest.Wakeup(); 63 | _cleaner.Join(); 64 | 65 | _rest.Dispose(); 66 | } 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /DataManager/Common/ConnectionParameters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GenericDataManager.Common 4 | { 5 | 6 | 7 | 8 | public struct ConnectionParameters 9 | { 10 | public string connection; 11 | public string modelResource; 12 | public string provider; 13 | public TimeSpan delay; 14 | 15 | 16 | 17 | 18 | 19 | 20 | public ConnectionParameters(string cnnStr, string modelName, int secondsDelay=30, string providerName = "System.Data.SqlClient") 21 | { 22 | connection = cnnStr.IndexOf(Konstants.MultipleActiveRecordSets)==-1? 23 | string.Concat(cnnStr, Konstants.MultipleActiveRecordSets, ";") : 24 | cnnStr; 25 | modelResource = string.Format(@"res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl", modelName); 26 | provider = providerName; 27 | delay = TimeSpan.FromSeconds(secondsDelay); 28 | 29 | } 30 | 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /DataManager/Common/ContextMap.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using GenericDataManager.Interfaces; 6 | 7 | namespace GenericDataManager.Common 8 | { 9 | public class ContextProviderThreadPair 10 | { 11 | readonly Thread _thread; 12 | readonly IContextProvider _provider; 13 | 14 | internal ContextProviderThreadPair(Thread thread, IContextProvider provider) 15 | { 16 | _thread = thread; 17 | _provider = provider; 18 | } 19 | 20 | public Thread Thread => _thread; 21 | public IContextProvider Provider => _provider; 22 | } 23 | 24 | internal class ContextMap : IContextMap 25 | { 26 | ConcurrentDictionary _map; 27 | //ReaderWriterLockSlim _lock; 28 | 29 | internal ContextMap(int estimatedThreadCount) 30 | { 31 | _map = new ConcurrentDictionary(estimatedThreadCount, estimatedThreadCount); 32 | //_lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); 33 | } 34 | 35 | void IContextMap.Add(Thread th, IContextProvider provider) 36 | { 37 | var tid = th.ManagedThreadId; 38 | if (!_map.ContainsKey(tid)) 39 | _map.TryAdd(tid, new ContextProviderThreadPair(th, provider)); 40 | } 41 | IContextProvider IContextMap.Remove(int id) 42 | { 43 | IContextProvider ret = null; 44 | 45 | 46 | if (_map.ContainsKey(id)) 47 | { 48 | ContextProviderThreadPair tmp = null; 49 | _map.TryRemove(id, out tmp); 50 | if (tmp != null) 51 | ret = tmp.Provider; 52 | } 53 | return ret; 54 | } 55 | ContextProviderThreadPair IContextMap.this[int tid] 56 | { 57 | get 58 | { 59 | ContextProviderThreadPair ret = null; 60 | _map.TryGetValue(tid, out ret); 61 | return ret; 62 | } 63 | } 64 | ContextProviderThreadPair[] IContextMap.Clear() 65 | { 66 | var values = new List(_map.Count); 67 | 68 | var keys = _map.Keys; 69 | foreach(var it in keys) 70 | { 71 | ContextProviderThreadPair tmp; 72 | _map.TryRemove(it, out tmp); 73 | if (tmp != null) 74 | values.Add(tmp); 75 | } 76 | return values.ToArray(); 77 | } 78 | 79 | int[] IContextMap.Keys => _map.Keys.ToArray(); 80 | ContextProviderThreadPair[] IContextMap.Values => _map.Values.ToArray(); 81 | bool IContextMap.Has(Thread thread) => _map.ContainsKey(thread.ManagedThreadId); 82 | int IContextMap.Count => _map.Count; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /DataManager/Common/ContextProviderCreator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using GenericDataManager.Common; 8 | using GenericDataManager.Interfaces; 9 | using GenericDataManager.Providers; 10 | 11 | namespace GenericDataManager.Common 12 | { 13 | public class ContextProviderCreator 14 | { 15 | readonly ConnectionParameters KConnection; 16 | readonly ExecutionPolicy KPolicy; 17 | 18 | 19 | public ContextProviderCreator(ConnectionParameters connection, ExecutionPolicy policy) 20 | { 21 | KConnection = connection; 22 | KPolicy = policy; 23 | } 24 | 25 | public IContextProvider Create(Thread th) 26 | { 27 | ContextProviderBase provider = null; 28 | 29 | switch (KPolicy.PeriodicDisposalStrategy) 30 | { 31 | case Strategy.DisposeLeastRecentlyUsed: 32 | provider = new SimpleContextProvider(KConnection); 33 | break; 34 | default: 35 | provider = new ContextProviderWithAge(KConnection); 36 | break; 37 | } 38 | 39 | return provider; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /DataManager/Common/Countable.cs: -------------------------------------------------------------------------------- 1 | namespace GenericDataManager.Common 2 | { 3 | public class Countable 4 | { 5 | public T Item { get; } 6 | public int Count { get; private set; } 7 | 8 | public Countable(T arg) 9 | { 10 | Item = arg; 11 | Count = 0; 12 | } 13 | public void Increment() 14 | { 15 | Count += 1; 16 | } 17 | public void Decrement() 18 | { 19 | Count = (Count > 0) ? Count - 1 : 0; 20 | } 21 | #if DEBUG 22 | public override string ToString() 23 | { 24 | return $"({Item}, {Count})"; 25 | } 26 | #endif 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /DataManager/Common/ExecutionPolicy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GenericDataManager.Common 4 | { 5 | public enum Strategy 6 | { 7 | DoNothing, 8 | DisposeWhenNotInUse, 9 | DisposeLeastRecentlyUsed, 10 | DisposeWithThread 11 | } 12 | 13 | public enum ManagerDisposalStrategy 14 | { 15 | Default, 16 | DisposeButThrowIfInUse, 17 | DisposeSilentlyEvenIfInUse 18 | 19 | // They have been removed after a comment received: 20 | // If it's time to dispose, why waiting and retrying or even not disposing at all? 21 | 22 | //RetryUntilDisposedOrFail, 23 | //FailIfNotDisposed, 24 | } 25 | 26 | 27 | public class ExecutionPolicy 28 | { 29 | public Strategy PeriodicDisposalStrategy { get; set; } 30 | public TimeSpan HeartBeat { get; set; } 31 | public TimeSpan MinimumAge { get; set; } 32 | public TimeSpan DisposalWait { get; set; } 33 | 34 | //public int RetryCount { get; set; } 35 | 36 | public ManagerDisposalStrategy FinalDisposalBehaviour { get; set; } 37 | 38 | 39 | public ExecutionPolicy() 40 | { 41 | PeriodicDisposalStrategy = Strategy.DoNothing; 42 | HeartBeat = Konstants.DefaultHeartbeat; 43 | MinimumAge = Konstants.DefaultMinimumAge; 44 | 45 | FinalDisposalBehaviour = ManagerDisposalStrategy.Default; 46 | DisposalWait = Konstants.DefaultDisposalWait; 47 | 48 | //RetryCount = Konstants.DefaultRetries; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /DataManager/Common/Konstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace GenericDataManager.Common 5 | { 6 | internal static class Konstants 7 | { 8 | internal const string MultipleActiveRecordSets = "MultipleActiveResultSets=True"; 9 | internal const string EntityFramework = "EntityFramework"; 10 | 11 | internal static readonly TimeSpan DefaultHeartbeat = TimeSpan.FromSeconds(3); 12 | internal static readonly TimeSpan DefaultMinimumAge = TimeSpan.FromSeconds(3); 13 | internal const int EstimatedThreads=10; 14 | 15 | internal static readonly TimeSpan DefaultDisposalWait = TimeSpan.FromSeconds(10); 16 | internal const int DefaultRetries=3; 17 | internal const string CleanerName= "Demon: GenericDataManagermon Cleaner"; 18 | 19 | internal static Tuple GetEntityFrameworkVersion() 20 | { 21 | var version = ""; 22 | var assemblies = System.AppDomain.CurrentDomain.GetAssemblies().Select(x => x.FullName).ToList(); 23 | foreach(var asm in assemblies) 24 | { 25 | var tmp = asm.Split(new char[] { ',', '{', '}' }, StringSplitOptions.RemoveEmptyEntries).Select(x=> x.Trim()).ToList(); 26 | if(string.Compare(tmp[0], EntityFramework, true)==0) 27 | { 28 | version = tmp[1].Split(new char[] {'='}, StringSplitOptions.RemoveEmptyEntries)[1]; 29 | break; 30 | } 31 | } 32 | 33 | var fragments = version.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).ToList().ConvertAll(x=> Int32.Parse(x)); 34 | return Tuple.Create(fragments[0], fragments[1], fragments[2], fragments[3]); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /DataManager/Common/QuickLock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace GenericDataManager.Common 10 | { 11 | /// 12 | /// Provides quick locking using Interlocked.CompareExchange with a specified delay 13 | /// 14 | public class QuickLock 15 | { 16 | const int K_MAX_TRIES = 10; 17 | 18 | volatile int _value; 19 | 20 | readonly int KDelay; 21 | readonly TimeSpan KMaxWaitingTime; 22 | readonly string KMessage; 23 | 24 | 25 | /// 26 | /// Instantiates a QuickLock with a specified duration to use between successive lock checking 27 | /// 28 | /// The duration between two successive lock checking 29 | #if NET45 30 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 31 | #endif 32 | public QuickLock(TimeSpan maxWait) 33 | { 34 | Interlocked.Exchange(ref _value, 0); 35 | 36 | KMaxWaitingTime = maxWait; 37 | KDelay = Convert.ToInt32(maxWait.TotalMilliseconds / K_MAX_TRIES); 38 | KMessage = $"Cannot continue further. Lock is longer than {TimeSpan.FromMilliseconds(KDelay * K_MAX_TRIES).TotalSeconds} second(s)"; 39 | 40 | } 41 | 42 | /// 43 | /// Tries 10 times to gain the lock. If it fails after 10 tries, throws TimeoutExpiration exception 44 | /// 45 | #if NET45 46 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 47 | #endif 48 | public void Lock() 49 | { 50 | var tries = K_MAX_TRIES; 51 | 52 | while (Interlocked.CompareExchange(ref _value, 1, 0)!=0) 53 | { 54 | if(tries--<1) 55 | throw new TimeoutException(KMessage); 56 | Thread.Sleep(KDelay); 57 | } 58 | } 59 | 60 | public bool IsLocked => Interlocked.CompareExchange(ref _value, -1, -1) == 1; 61 | 62 | 63 | 64 | /// 65 | /// Unlocked a previous lock 66 | /// 67 | #if NET45 68 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 69 | #endif 70 | public void Unlock() { 71 | Interlocked.Exchange(ref _value, 0); 72 | } 73 | 74 | #if DEBUG 75 | public override string ToString() 76 | { 77 | Interlocked.MemoryBarrier(); 78 | var ret= $"{_value}"; 79 | return ret; 80 | } 81 | #endif 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /DataManager/Common/SandBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericDataManager.Common 8 | { 9 | public class SandBox 10 | { 11 | public static void TRY(Action action, Action handler) 12 | { 13 | try 14 | { 15 | action(); 16 | } 17 | catch(Exception ex) 18 | { 19 | handler(ex); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /DataManager/Common/SharedData.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | 3 | namespace GenericDataManager.Common 4 | { 5 | public class SharedData where T:class 6 | { 7 | T _data; 8 | ReaderWriterLockSlim _lock; 9 | 10 | public SharedData(T arg) 11 | { 12 | Interlocked.Exchange(ref _data, arg); 13 | _lock = new ReaderWriterLockSlim(); 14 | } 15 | 16 | public T Value 17 | { 18 | get 19 | { 20 | _lock.EnterReadLock(); 21 | var ret = Interlocked.CompareExchange(ref _data, default(T), default(T)); 22 | _lock.ExitReadLock(); 23 | 24 | return ret; 25 | } 26 | set 27 | { 28 | _lock.EnterWriteLock(); 29 | Interlocked.Exchange(ref _data, value); 30 | _lock.ExitWriteLock(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /DataManager/Common/ThreadRest.cs: -------------------------------------------------------------------------------- 1 | // /******************************************************* 2 | // * Copyright (C) 2016 Suheyl Z 3 | // * 4 | // * This file is part of DataManager. 5 | // * 6 | // * It can not be copied and/or distributed without the express 7 | // * permission. 8 | // *******************************************************/ 9 | 10 | using System; 11 | using System.Threading; 12 | 13 | namespace GenericDataManager.Common 14 | { 15 | public class ThreadRest:IDisposable 16 | { 17 | readonly TimeSpan _waitDuration; 18 | readonly ManualResetEventSlim _signal; 19 | 20 | public ThreadRest(TimeSpan duration) 21 | { 22 | _waitDuration = duration; 23 | _signal = new ManualResetEventSlim(false); 24 | } 25 | 26 | public void Dispose() => _signal.Dispose(); 27 | public bool Snooze()=> _signal.Wait(_waitDuration); 28 | public void Wakeup() => _signal.Set(); 29 | public void Reset() => _signal.Reset(); 30 | 31 | public bool ShouldContinue => !_signal.IsSet; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /DataManager/Common/ThreadsMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Diagnostics.Contracts; 7 | using System.Collections; 8 | 9 | namespace GenericDataManager.Common 10 | { 11 | public class ThreadMap4Items: 12 | IEnumerable where TValue:class 13 | { 14 | ReaderWriterLockSlim _gate; 15 | IDictionary> _map; 16 | 17 | 18 | public ThreadMap4Items(int capacity=64) 19 | { 20 | _gate = new ReaderWriterLockSlim(); 21 | _map = new Dictionary>(capacity); 22 | } 23 | 24 | public TValue Add(TKey key, TValue value) 25 | { 26 | Contract.Requires(value != null); 27 | 28 | var item = new Countable(value); 29 | 30 | _gate.EnterWriteLock(); 31 | _map.Add(key, item); 32 | _gate.ExitWriteLock(); 33 | 34 | return item.Item; 35 | } 36 | public TValue Delete(TKey key) 37 | { 38 | Contract.Ensures(Contract.Result() != null); 39 | 40 | var ret = this[key]; 41 | 42 | _gate.EnterWriteLock(); 43 | _map.Remove(key); 44 | _gate.ExitWriteLock(); 45 | 46 | return ret; 47 | } 48 | 49 | public bool Has(TKey key) 50 | { 51 | var ret = false; 52 | 53 | _gate.EnterReadLock(); 54 | ret = _map.ContainsKey(key); 55 | _gate.ExitReadLock(); 56 | 57 | return ret; 58 | } 59 | public TValue this[TKey key] 60 | { 61 | get 62 | { 63 | TValue ret = default(TValue); 64 | 65 | _gate.EnterReadLock(); 66 | if (_map.ContainsKey(key)) 67 | { 68 | var item = _map[key]; 69 | item.Increment(); 70 | ret = item.Item; 71 | } 72 | _gate.ExitReadLock(); 73 | 74 | return ret; 75 | } 76 | 77 | } 78 | public TValue this[int idx] 79 | { 80 | get 81 | { 82 | TValue ret = default(TValue); 83 | 84 | _gate.EnterReadLock(); 85 | 86 | if (idx<_map.Count) 87 | { 88 | var obj = _map.ElementAt(idx); 89 | ret = obj.Value.Item; 90 | } 91 | _gate.ExitReadLock(); 92 | return ret; 93 | } 94 | } 95 | public int Free(TKey key) 96 | { 97 | var ret = 0; 98 | 99 | _gate.EnterReadLock(); 100 | _map[key].Decrement(); 101 | ret = _map[key].Count; 102 | _gate.ExitReadLock(); 103 | 104 | return ret; 105 | } 106 | public int ValueCount(TKey key) 107 | { 108 | var ret = 0; 109 | _gate.EnterReadLock(); 110 | ret = _map[key].Count; 111 | _gate.ExitReadLock(); 112 | 113 | return ret; 114 | } 115 | 116 | #if DEBUG 117 | public override string ToString() 118 | { 119 | var ret = ""; 120 | 121 | _gate.EnterReadLock(); 122 | ret = string.Join(", ", _map.Keys); 123 | _gate.ExitReadLock(); 124 | 125 | return ret; 126 | } 127 | #endif 128 | 129 | public List Clear() 130 | { 131 | var ret = new List(_map.Count); 132 | 133 | _gate.EnterReadLock(); 134 | ret = _map.Values.Select(x => x.Item).ToList(); 135 | _gate.ExitReadLock(); 136 | 137 | _gate.EnterWriteLock(); 138 | _map.Clear(); 139 | _gate.ExitWriteLock(); 140 | 141 | return ret; 142 | } 143 | 144 | IEnumerator IEnumerable.GetEnumerator() 145 | { 146 | var values = _map.Values.Select(x => x.Item).ToList(); 147 | foreach (var it in values) 148 | yield return it; 149 | } 150 | 151 | IEnumerator IEnumerable.GetEnumerator() 152 | { 153 | return (this as IEnumerable).GetEnumerator() as IEnumerator; 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /DataManager/ContextConsumers/ContextConsumerBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | using GenericDataManager.Common; 4 | using GenericDataManager.Interfaces; 5 | 6 | namespace GenericDataManager.Consumers 7 | { 8 | public class ContextConsumerBase : IContextConsumer 9 | { 10 | protected IContextProvider _provider; 11 | private string _key; 12 | 13 | protected static readonly Tuple EntityFrameworkVersion = Konstants.GetEntityFrameworkVersion(); 14 | 15 | internal ContextConsumerBase(IContextProvider arg) 16 | { 17 | _provider = arg; 18 | } 19 | 20 | void IContextConsumer.Init(IContextProvider arg, string key) 21 | { 22 | _provider = arg; 23 | _key = key; 24 | } 25 | 26 | protected void Save(bool useTransaction = false) 27 | { 28 | if (EntityFrameworkVersion.Item1 <= 5) 29 | EnsureConnectionOpen(); 30 | 31 | 32 | try 33 | { 34 | _provider.DataContext.SaveChanges(); 35 | } 36 | catch (Exception ex) 37 | { 38 | 39 | throw; 40 | } 41 | 42 | if (EntityFrameworkVersion.Item1 <= 5) 43 | EnsureConnectionOpen(); 44 | } 45 | 46 | protected void EnsureConnectionOpen() 47 | { 48 | if (_provider.ObjectContext.Connection.State != ConnectionState.Open) 49 | _provider.ObjectContext.Connection.Open(); 50 | } 51 | 52 | #region IDisposable Support 53 | private bool disposedValue = false; // To detect redundant calls 54 | 55 | protected virtual void Dispose(bool disposing) 56 | { 57 | if (!disposedValue) 58 | { 59 | if (disposing) 60 | { 61 | _provider.Release(this, _key); 62 | //_provider = null; -- not required as cleaner will take care of the providers 63 | } 64 | disposedValue = true; 65 | } 66 | } 67 | 68 | ~ContextConsumerBase() 69 | { 70 | Dispose(false); 71 | } 72 | 73 | void IDisposable.Dispose() 74 | { 75 | // Do not change this code. Put cleanup code in Dispose(bool disposing) above. 76 | Dispose(true); 77 | GC.SuppressFinalize(this); 78 | } 79 | #endregion 80 | 81 | 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /DataManager/ContextConsumers/EntityReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.Linq; 5 | using GenericDataManager.Interfaces; 6 | 7 | namespace GenericDataManager.Consumers 8 | { 9 | public class EntityReader : 10 | ContextConsumerBase, 11 | IEntityReader where T:class 12 | { 13 | internal EntityReader(IContextProvider arg):base(arg) 14 | {} 15 | 16 | 17 | IQueryable IEntityReader.All(System.Linq.Expressions.Expression> expr) 18 | { 19 | return expr == null ? _provider.DataContext.Set() : _provider.DataContext.Set().Where(expr); 20 | } 21 | long IEntityReader.Count(System.Linq.Expressions.Expression> expr) 22 | { 23 | return expr == null ? _provider.DataContext.Set().LongCount() : _provider.DataContext.Set().LongCount(expr); 24 | } 25 | bool IEntityReader.Exists(System.Linq.Expressions.Expression> expr) 26 | { 27 | return _provider.DataContext.Set().Count(expr)>0; 28 | } 29 | T IEntityReader.One(System.Linq.Expressions.Expression> expr) 30 | { 31 | var obj = expr == null ? _provider.DataContext.Set().FirstOrDefault() : _provider.DataContext.Set().Where(expr).FirstOrDefault(); 32 | return obj; 33 | } 34 | IEnumerable IEntityReader.ReadOnly(System.Linq.Expressions.Expression> expr) 35 | { 36 | var list = (expr == null ? 37 | _provider.DataContext.Set() : 38 | _provider.DataContext.Set().Where(expr) 39 | ).AsNoTracking().ToList(); 40 | 41 | return list; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /DataManager/ContextConsumers/EntityReaderWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.Entity; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | using GenericDataManager.Interfaces; 8 | 9 | namespace GenericDataManager.Consumers 10 | { 11 | public class EntityReaderWriter : 12 | EntityWriter, 13 | IEntityReaderWriter 14 | where TEntity : class 15 | { 16 | internal EntityReaderWriter(IContextProvider arg) : base(arg) { } 17 | 18 | IQueryable IEntityReader.All(System.Linq.Expressions.Expression> expr) 19 | { 20 | return expr == null ? _provider.DataContext.Set() : _provider.DataContext.Set().Where(expr); 21 | } 22 | long IEntityReader.Count(System.Linq.Expressions.Expression> expr) 23 | { 24 | return expr == null ? _provider.DataContext.Set().LongCount() : _provider.DataContext.Set().LongCount(expr); 25 | } 26 | bool IEntityReader.Exists(System.Linq.Expressions.Expression> expr) 27 | { 28 | return _provider.DataContext.Set().Count(expr) > 0; 29 | } 30 | TEntity IEntityReader.One(System.Linq.Expressions.Expression> expr) 31 | { 32 | var obj = expr == null ? _provider.DataContext.Set().FirstOrDefault() : _provider.DataContext.Set().Where(expr).FirstOrDefault(); 33 | return obj; 34 | } 35 | IEnumerable IEntityReader.ReadOnly(System.Linq.Expressions.Expression> expr) 36 | { 37 | var list = (expr == null ? 38 | _provider.DataContext.Set() : 39 | _provider.DataContext.Set().Where(expr) 40 | ).AsNoTracking().ToList(); 41 | 42 | return list; 43 | } 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /DataManager/ContextConsumers/EntityWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | #if EF5 5 | using System.Data.EntityClient; 6 | using System.Data.Objects; 7 | #else 8 | using System.Data.Entity; 9 | using System.Data.Entity.Core.Objects; 10 | using System.Data.Entity.Core.EntityClient; 11 | #endif 12 | using System.Linq; 13 | using System.Linq.Expressions; 14 | using GenericDataManager.Interfaces; 15 | 16 | namespace GenericDataManager.Consumers 17 | { 18 | public class EntityWriter : 19 | ContextConsumerBase, 20 | IEntityWriter where T : class 21 | { 22 | internal EntityWriter(IContextProvider arg):base(arg) 23 | {} 24 | 25 | void IEntityWriter.Add(IEnumerable arg) 26 | { 27 | 28 | foreach (var it in arg) 29 | _provider.DataContext.Set().Add(it); 30 | 31 | Save(true); 32 | } 33 | void IEntityWriter.Add(T arg) 34 | { 35 | _provider.DataContext.Set().Add(arg); 36 | Save(); 37 | } 38 | 39 | void IEntityWriter.Delete(IEnumerable list) 40 | { 41 | foreach(var it in list) 42 | { 43 | _provider.DataContext.Set().Remove(it); 44 | _provider.ObjectContext.ObjectStateManager.ChangeObjectState(it, EntityState.Deleted); 45 | } 46 | _provider.DataContext.SaveChanges(); 47 | } 48 | 49 | void IEntityWriter.Delete(Expression> expr) 50 | { 51 | var list = _provider.DataContext.Set().Where(expr); 52 | foreach (var it in list) 53 | _provider.DataContext.Set().Remove(it); 54 | Save(true); 55 | } 56 | void IEntityWriter.Delete(T arg) 57 | { 58 | _provider.DataContext.Set().Remove(arg); 59 | Save(); 60 | } 61 | 62 | void IEntityWriter.Update(IEnumerable list) 63 | { 64 | foreach (var it in list) 65 | _provider.ObjectContext.ObjectStateManager.ChangeObjectState(it, EntityState.Modified); 66 | 67 | _provider.DataContext.SaveChanges(); 68 | } 69 | 70 | void IEntityWriter.Update(T arg) 71 | { 72 | _provider.ObjectContext.ObjectStateManager.ChangeObjectState(arg, EntityState.Modified); 73 | if (_provider.ObjectContext.ObjectStateManager.GetObjectStateEntry(arg).State == EntityState.Modified) 74 | Save(); 75 | } 76 | void IEntityWriter.Update(Expression> expr, Action action) 77 | { 78 | var list = _provider.DataContext.Set().Where(expr); 79 | foreach (var it in list) 80 | { 81 | action(it); 82 | _provider.ObjectContext.ObjectStateManager.ChangeObjectState(it, EntityState.Modified); 83 | } 84 | Save(true); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /DataManager/ContextConsumers/SqlDirect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.Common; 5 | using GenericDataManager.Common; 6 | using GenericDataManager.Interfaces; 7 | 8 | namespace GenericDataManager.Consumers 9 | { 10 | internal class SqlDirect : ContextConsumerBase, ISqlDirect 11 | { 12 | Stack _stk; 13 | internal SqlDirect(IContextProvider arg) : base(arg) 14 | { 15 | _stk = new Stack(); 16 | } 17 | 18 | T ISqlDirect.ExecuteScalar(string name, Dictionary args) 19 | { 20 | T ret = default(T); 21 | 22 | using (var cmd = _provider.DataContext.Database.Connection.CreateCommand()) 23 | { 24 | cmd.CommandText = name; 25 | cmd.CommandType = System.Data.CommandType.Text; 26 | if (args != null) 27 | AttachParameters(cmd, args); 28 | 29 | EnsureConnectionOpen(); 30 | var obj = cmd.ExecuteScalar(); 31 | ret = (T) Convert.ChangeType(obj, typeof(T)); 32 | } 33 | return ret; 34 | } 35 | void ISqlDirect.ExecuteNonQuery(string name, Dictionary args) 36 | { 37 | using (var cmd = _provider.DataContext.Database.Connection.CreateCommand()) 38 | { 39 | cmd.CommandText = name; 40 | cmd.CommandType = System.Data.CommandType.Text; 41 | 42 | if (args != null) 43 | AttachParameters(cmd, args); 44 | 45 | EnsureConnectionOpen(); 46 | cmd.ExecuteNonQuery(); 47 | } 48 | } 49 | IDataReader ISqlDirect.ExecuteReader(string sql, Dictionary args) 50 | { 51 | using (var cmd = _provider.DataContext.Database.Connection.CreateCommand()) 52 | { 53 | cmd.CommandText = sql; 54 | cmd.CommandType = System.Data.CommandType.Text; 55 | 56 | if (args != null) 57 | AttachParameters(cmd, args); 58 | var rd = cmd.ExecuteReader(CommandBehavior.Default); 59 | _stk.Push(rd); 60 | return rd; 61 | } 62 | } 63 | long ISqlDirect.GetNumber(string name) 64 | { 65 | EnsureConnectionOpen(); 66 | return (this as ISqlDirect).ExecuteScalar($"SELECT NEXT VALUE FOR [{name}]"); 67 | } 68 | 69 | 70 | 71 | private void AttachParameters(DbCommand cmd, Dictionary args) 72 | { 73 | foreach (var key in args.Keys) 74 | { 75 | var p = cmd.CreateParameter(); 76 | p.ParameterName = key.StartsWith("@")? key: "@"+key; 77 | p.Value = args[key]; 78 | cmd.Parameters.Add(p); 79 | } 80 | } 81 | 82 | protected override void Dispose(bool disposing) 83 | { 84 | var builder = new AggregateExceptionBuilder("Some DataReader objects might be open"); 85 | 86 | while (_stk.Count > 0) 87 | { 88 | var rd = _stk.Pop(); 89 | if (!rd.IsClosed) 90 | SandBox.TRY(() => rd.Dispose(), (ex) => builder.Add(ex)); 91 | } 92 | 93 | base.Dispose(disposing); 94 | 95 | if (builder.HasErrors) 96 | throw builder.ToAggregateException(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /DataManager/ContextProviders/ContextProviderBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.Entity; 5 | 6 | using System.Data.Entity.Infrastructure; 7 | 8 | #if EF5 9 | using System.Data.EntityClient; 10 | using System.Data.Objects; 11 | #else 12 | using System.Data.Entity.Core.Objects; 13 | using System.Data.Entity.Core.EntityClient; 14 | #endif 15 | 16 | using System.Threading; 17 | using GenericDataManager.Common; 18 | using GenericDataManager.Consumers; 19 | using GenericDataManager.Interfaces; 20 | 21 | namespace GenericDataManager.Providers 22 | { 23 | internal class ContextProviderBase : 24 | IDataRepository, 25 | IContextProvider, 26 | IDisposable 27 | { 28 | protected readonly DbContext _ctx; 29 | protected readonly ObjectContext _objctx; 30 | protected readonly IDictionary _map; 31 | protected readonly int _threadId; 32 | 33 | 34 | readonly DateTime _createdAt; 35 | 36 | internal ContextProviderBase(ConnectionParameters arg) 37 | { 38 | _threadId = Thread.CurrentThread.ManagedThreadId; 39 | _createdAt = DateTime.Now; 40 | 41 | _map = new SortedDictionary(); 42 | 43 | var builder = new EntityConnectionStringBuilder 44 | { 45 | ProviderConnectionString = arg.connection, 46 | Metadata = arg.modelResource, 47 | Provider = arg.provider 48 | }; 49 | 50 | if (!builder.ProviderConnectionString.Contains(Konstants.MultipleActiveRecordSets)) 51 | { 52 | if (builder.ProviderConnectionString.EndsWith(";")) 53 | builder.ProviderConnectionString += $"{Konstants.MultipleActiveRecordSets};"; 54 | else 55 | builder.ProviderConnectionString += $";{Konstants.MultipleActiveRecordSets};"; 56 | } 57 | 58 | _ctx = new DbContext(builder.ToString()); 59 | var adapter = _ctx as IObjectContextAdapter; 60 | if (adapter != null) 61 | _objctx = adapter.ObjectContext; 62 | else 63 | throw new InvalidOperationException($"Could not create object context from the DbContext on {Thread.CurrentThread.ManagedThreadId}"); 64 | 65 | EnsureWorkingConnection(); 66 | } 67 | 68 | internal int ThreadId => _threadId; 69 | internal int ConsumerCount => _map.Count; 70 | 71 | protected void EnsureWorkingConnection() 72 | { 73 | if (_objctx.Connection.State != ConnectionState.Open) 74 | _objctx.Connection.Open(); 75 | } 76 | 77 | 78 | private string Key() => $"{typeof(T1).Name}:{typeof(T2).Name}"; 79 | public virtual DbContext DataContext => _ctx; 80 | public virtual ObjectContext ObjectContext => _objctx; 81 | 82 | 83 | 84 | public virtual void Release(IContextConsumer arg, string key) 85 | { 86 | if (!_map.ContainsKey(key)) 87 | throw new ObjectDisposedException($"ContextConsumer could not be found. Error in thread {Thread.CurrentThread.ManagedThreadId}"); 88 | 89 | _map.Remove(key); 90 | } 91 | 92 | ISqlDirect IDataRepository.Sql 93 | { 94 | get 95 | { 96 | var key = Key(); 97 | if (!_map.ContainsKey(key)) 98 | { 99 | var consumer = new SqlDirect(this); 100 | (consumer as IContextConsumer).Init(this, key); 101 | _map.Add(key, consumer); 102 | } 103 | return _map[key] as ISqlDirect; 104 | } 105 | } 106 | IEntityReader IDataRepository.GetReader() 107 | { 108 | var key = Key, TYPE>(); 109 | if (!_map.ContainsKey(key)) 110 | { 111 | var consumer = new EntityReader(this); 112 | (consumer as IContextConsumer).Init(this, key); 113 | _map.Add(key, consumer); 114 | } 115 | return _map[key] as IEntityReader; 116 | } 117 | IEntityWriter IDataRepository.GetWriter() 118 | { 119 | var key = Key, TEntity>(); 120 | if (!_map.ContainsKey(key)) 121 | { 122 | var consumer = new EntityWriter(this); 123 | (consumer as IContextConsumer).Init(this, key); 124 | _map.Add(key, consumer); 125 | } 126 | return _map[key] as IEntityWriter; 127 | } 128 | IEntityReaderWriter IDataRepository.Get() 129 | { 130 | var key = Key, TEntity>(); 131 | if (!_map.ContainsKey(key)) 132 | { 133 | var consumer = new EntityReaderWriter(this); 134 | (consumer as IContextConsumer).Init(this, key); 135 | _map.Add(key, consumer); 136 | } 137 | return _map[key] as IEntityReaderWriter; 138 | } 139 | 140 | #region IDisposable Support 141 | private bool disposedValue = false; // To detect redundant calls 142 | 143 | protected virtual void Dispose(bool disposing) 144 | { 145 | if (!disposedValue) 146 | { 147 | if (disposing) 148 | { 149 | var keys = _map.Keys; 150 | foreach (var key in keys) 151 | { 152 | var consumer = _map[key]; 153 | if(consumer!=null) 154 | consumer.Dispose(); 155 | } 156 | 157 | _map.Clear(); 158 | 159 | _objctx.Connection.Close(); 160 | 161 | _objctx.Dispose(); 162 | _ctx.Dispose(); 163 | } 164 | disposedValue = true; 165 | } 166 | } 167 | 168 | ~ContextProviderBase() 169 | { 170 | Dispose(false); 171 | } 172 | 173 | public void Dispose() 174 | { 175 | Dispose(true); 176 | GC.SuppressFinalize(this); 177 | } 178 | #endregion 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /DataManager/ContextProviders/ContextProviderWithAge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity; 3 | #if EF5 4 | using System.Data.EntityClient; 5 | using System.Data.Objects; 6 | #else 7 | using System.Data.Entity.Core.Objects; 8 | using System.Data.Entity.Core.EntityClient; 9 | #endif 10 | using GenericDataManager.Common; 11 | 12 | namespace GenericDataManager.Providers 13 | { 14 | internal class ContextProviderWithAge : ContextProviderBase 15 | { 16 | readonly DateTime _createdAt; 17 | DateTime _lastUsed; 18 | 19 | 20 | internal ContextProviderWithAge(ConnectionParameters arg):base(arg) 21 | { 22 | _createdAt = DateTime.Now; 23 | _lastUsed = _createdAt; 24 | ObjectContext.SavingChanges += (sender, args) => _lastUsed = DateTime.Now; 25 | } 26 | 27 | internal TimeSpan Age => DateTime.Now.Subtract(_createdAt); 28 | internal TimeSpan LastUsed => DateTime.Now.Subtract(_lastUsed); 29 | 30 | 31 | public override DbContext DataContext 32 | { 33 | get 34 | { 35 | _lastUsed = DateTime.Now; 36 | return base.DataContext; 37 | } 38 | } 39 | public override ObjectContext ObjectContext 40 | { 41 | get 42 | { 43 | _lastUsed = DateTime.Now; 44 | return base.ObjectContext; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /DataManager/ContextProviders/LegacyProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | using GenericDataManager.Interfaces; 7 | 8 | #if EF5 9 | using System.Data.EntityClient; 10 | using System.Data.Objects; 11 | #else 12 | using System.Data.Entity; 13 | using System.Data.Entity.Core.Objects; 14 | using System.Data.Entity.Core.EntityClient; 15 | #endif 16 | 17 | namespace GenericDataManager.Providers 18 | { 19 | class LegacyProvider : 20 | IEntityGatewayClient, 21 | IEntityReaderWriter 22 | where TEntity:class 23 | { 24 | private int _key; 25 | private IEntityGateway _provider; 26 | 27 | 28 | void IEntityGatewayClient.Register(IEntityGateway arg, int key) 29 | { 30 | Debug.Assert(arg != null); 31 | _provider = arg; 32 | _key = key; 33 | } 34 | void IDisposable.Dispose() 35 | { 36 | _provider.Release(_key); 37 | } 38 | 39 | 40 | 41 | IQueryable IEntityReader.All(Expression> expr) 42 | { 43 | return expr == null ? 44 | _provider.Set() : _provider.Set().Where(expr); 45 | } 46 | long IEntityReader.Count(Expression> expr) 47 | { 48 | return expr == null ? 49 | _provider.Set().AsNoTracking().LongCount() : _provider.Set().AsNoTracking().LongCount(expr); 50 | 51 | } 52 | IEnumerable IEntityReader.ReadOnly(Expression> expr) 53 | { 54 | var objects = expr == null ? 55 | _provider.Set().AsNoTracking() : 56 | _provider.Set().AsNoTracking().Where(expr); 57 | return objects.ToList(); 58 | 59 | } 60 | bool IEntityReader.Exists(Expression> expr) 61 | { 62 | return _provider.Set().AsNoTracking().Count(expr) > 0; 63 | } 64 | TEntity IEntityReader.One(Expression> expr) 65 | { 66 | return expr == null ? _provider.Set().FirstOrDefault() : _provider.Set().FirstOrDefault(expr); 67 | } 68 | 69 | 70 | 71 | void IEntityWriter.Add(TEntity arg) 72 | { 73 | _provider.Set().Add(arg); 74 | _provider.Save(); 75 | } 76 | void IEntityWriter.Add(IEnumerable arg) 77 | { 78 | foreach(var it in arg) 79 | _provider.Set().Add(it); 80 | _provider.Save(); 81 | } 82 | void IEntityWriter.Update(TEntity arg) 83 | { 84 | _provider.Save(); 85 | } 86 | void IEntityWriter.Update(Expression> expr, Action statement) 87 | { 88 | var items = _provider.Set().Where(expr); 89 | foreach (var it in items) 90 | statement(it); 91 | _provider.Save(); 92 | } 93 | void IEntityWriter.Delete(Expression> expr) 94 | { 95 | var list = _provider.Set().Where(expr); 96 | foreach (var it in list) 97 | _provider.Set().Remove(it); 98 | _provider.Save(); 99 | } 100 | void IEntityWriter.Delete(TEntity arg) 101 | { 102 | _provider.Set().Remove(arg); 103 | _provider.Save(); 104 | } 105 | 106 | void IEntityWriter.Update(IEnumerable list) 107 | { 108 | foreach (var it in list) 109 | _provider.ObjectContext.ObjectStateManager.ChangeObjectState(it, EntityState.Modified); 110 | 111 | _provider.Save(); 112 | } 113 | 114 | void IEntityWriter.Delete(IEnumerable list) 115 | { 116 | foreach (var it in list) 117 | _provider.Set().Remove(it); 118 | _provider.Save(); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /DataManager/ContextProviders/SimpleContextProvider.cs: -------------------------------------------------------------------------------- 1 | using GenericDataManager.Common; 2 | 3 | namespace GenericDataManager.Providers 4 | { 5 | internal class SimpleContextProvider: ContextProviderBase 6 | { 7 | internal SimpleContextProvider(ConnectionParameters arg) : base(arg) { } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /DataManager/DataManager.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1279A4CA-914A-4899-91CA-07B36915CC8D} 8 | Library 9 | Properties 10 | GenericDataManager 11 | DataManager.Generic 12 | v4.5 13 | 512 14 | 15 | 1 16 | True 17 | False 18 | False 19 | 20 | 21 | AssemblyVersionAttribute 22 | Properties\AssemblyInfo.cs 23 | 2.0.7.3 24 | None.None.None.IncrementOnDemand 25 | 26 | 27 | 28 | 29 | true 30 | full 31 | false 32 | bin\Debug\ 33 | DEBUG;TRACE 34 | prompt 35 | 4 36 | True 37 | False 38 | True 39 | False 40 | False 41 | False 42 | True 43 | True 44 | True 45 | True 46 | True 47 | True 48 | True 49 | True 50 | False 51 | True 52 | False 53 | True 54 | False 55 | False 56 | False 57 | False 58 | True 59 | False 60 | True 61 | True 62 | True 63 | False 64 | False 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | True 73 | False 74 | False 75 | True 76 | Pre and Post 77 | Build 78 | 0 79 | false 80 | AssemblyVersionAttribute 81 | Properties\AssemblyInfo.cs 82 | False 83 | False 84 | False 85 | 86 | 87 | 88 | none 89 | true 90 | bin\Release\ 91 | TRACE;NET45 92 | prompt 93 | 4 94 | Auto 95 | false 96 | false 97 | AssemblyVersionAttribute 98 | Properties\AssemblyInfo.cs 99 | True 100 | True 101 | False 102 | None.None.Increment.None 103 | 104 | 105 | true 106 | 107 | 108 | DataManager.snk 109 | 110 | 111 | 112 | ..\packages\EntityFramework.6.0.0\lib\net40\EntityFramework.dll 113 | True 114 | 115 | 116 | ..\packages\EntityFramework.6.0.0\lib\net40\EntityFramework.SqlServer.dll 117 | True 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 177 | -------------------------------------------------------------------------------- /DataManager/DataManager.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuheylZ/GenericDataManager/6fa8bd6da2dd7187dfde213f86bbcd4aba8d97a2/DataManager/DataManager.snk -------------------------------------------------------------------------------- /DataManager/DataManagers/DataManagerWithPolicy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics.Contracts; 3 | using System.Threading; 4 | using GenericDataManager.Common; 5 | using GenericDataManager.Interfaces; 6 | using GenericDataManager.Providers; 7 | using GenericDataManager.Strategies; 8 | 9 | namespace GenericDataManager 10 | { 11 | /// 12 | /// DataManager keeps track of all EntityOperations and provides a single instantiation of EntityOperation of each particular entity. 13 | /// 14 | public class DataManagerWithPolicy: 15 | IDataRepositoryProvider 16 | { 17 | static readonly IContextMap _map = new ContextMap(Konstants.EstimatedThreads); 18 | 19 | readonly ConnectionParameters KConnectionParameters; 20 | readonly ExecutionPolicy KPolicy; 21 | 22 | readonly ICleaner _cleaner; 23 | readonly ContextProviderCreator _creator; 24 | 25 | /// 26 | /// Establishes the connection and initializes internal structures 27 | /// 28 | /// Settings for the connection, model etc 29 | /// Policy for this datamanager 30 | public DataManagerWithPolicy(ConnectionParameters arg, ExecutionPolicy policy) 31 | { 32 | Contract.Requires(!string.IsNullOrEmpty(arg.connection)); 33 | Contract.Requires(!string.IsNullOrEmpty(arg.modelResource)); 34 | 35 | KConnectionParameters = arg; 36 | KPolicy = policy; 37 | 38 | _creator = new ContextProviderCreator(KConnectionParameters, KPolicy); 39 | _cleaner = CreateCleaner(KPolicy.PeriodicDisposalStrategy); 40 | 41 | _cleaner.Start(); 42 | 43 | //This is done so that the model can be loaded 44 | var rep = (this as IDataRepositoryProvider).Repository; 45 | } 46 | 47 | ICleaner CreateCleaner(Strategy strategy) 48 | { 49 | ICleaner cleaner; 50 | 51 | switch (strategy) 52 | { 53 | case Strategy.DisposeWithThread: 54 | cleaner = new Cleaner(_map, KPolicy); 55 | break; 56 | case Strategy.DisposeWhenNotInUse: 57 | cleaner = new Cleaner(_map, KPolicy); 58 | break; 59 | case Strategy.DisposeLeastRecentlyUsed: 60 | cleaner = new Cleaner(_map, KPolicy); 61 | break; 62 | default: 63 | cleaner = new Cleaner(_map, KPolicy); 64 | break; 65 | } 66 | return cleaner; 67 | } 68 | 69 | /// 70 | /// Provides the access to the custom repositories through the Get() method 71 | /// 72 | public IDataRepository Repository 73 | { 74 | get 75 | { 76 | var thread = Thread.CurrentThread; 77 | 78 | if (!_map.Has(thread)) 79 | _map.Add(thread, _creator.Create(thread)); 80 | 81 | return _map[thread.ManagedThreadId].Provider as IDataRepository; 82 | } 83 | } 84 | 85 | 86 | #if DEBUG 87 | public override string ToString() 88 | { 89 | return $"_map: {_map.ToString()}"; 90 | } 91 | #endif 92 | 93 | 94 | #region IDisposable Support 95 | private bool _disposedValue = false; 96 | 97 | protected virtual void Dispose(bool disposing) 98 | { 99 | if (!_disposedValue) 100 | { 101 | if (disposing) 102 | { 103 | _cleaner.Dispose(); 104 | } 105 | _disposedValue = true; 106 | } 107 | } 108 | 109 | ~DataManagerWithPolicy() 110 | { 111 | Dispose(false); 112 | } 113 | 114 | void IDisposable.Dispose() 115 | { 116 | Dispose(true); 117 | GC.SuppressFinalize(this); 118 | } 119 | #endregion 120 | 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /DataManager/DataManagers/LegacyDataManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity; 3 | using System.Data.Entity.Infrastructure; 4 | #if EF5 5 | using System.Data.EntityClient; 6 | using System.Data.Objects; 7 | #else 8 | using System.Data.Entity.Core.Objects; 9 | using System.Data.Entity.Core.EntityClient; 10 | #endif 11 | using System.Diagnostics.Contracts; 12 | using System.Threading; 13 | using GenericDataManager.Common; 14 | using GenericDataManager.Interfaces; 15 | using GenericDataManager.Providers; 16 | 17 | namespace GenericDataManager 18 | { 19 | 20 | /// 21 | /// DataManager keeps track of all EntityOperations and provides a single instantiation of EntityOperation of each particular entity. 22 | /// 23 | public class DataManager : 24 | IEntityGateway, 25 | IDataManager 26 | { 27 | ConnectionParameters KConnectionParameters; 28 | static ThreadMap4Items _map; 29 | 30 | /// 31 | /// Establishes the connection and initializes internal structures 32 | /// 33 | /// basic connection string 34 | /// the name of the model without the extensions 35 | /// provider name, default is System.Data.SqlClient 36 | /// The maximum duration for after which the operation must fail if lock could not be acquired. 37 | public DataManager(ConnectionParameters arg) 38 | { 39 | Contract.Requires(!string.IsNullOrEmpty(arg.connection)); 40 | Contract.Requires(!string.IsNullOrEmpty(arg.modelResource)); 41 | 42 | KConnectionParameters = arg; 43 | _map = new ThreadMap4Items(16); 44 | _map.Add(Thread.CurrentThread.ManagedThreadId, CreateDbContext()); 45 | } 46 | 47 | void IEntityGateway.Release(int id) 48 | { 49 | if (_map.Has(id)) 50 | { 51 | var count = _map.Free(id); 52 | } 53 | } 54 | 55 | /// 56 | /// Retrieves the EntityOperation for a particular entity type. Only a single instance is instantiated 57 | /// 58 | /// 59 | /// 60 | IEntityReaderWriter IDataManager.Get() { 61 | Contract.Ensures(Contract.Result>() != null); 62 | 63 | var clientThreadId = Thread.CurrentThread.ManagedThreadId; 64 | var provider = (this as IEntityGateway); 65 | 66 | 67 | IEntityReaderWriter ret = null; 68 | if (!_map.Has(clientThreadId)) 69 | _map.Add(clientThreadId, CreateDbContext()); 70 | 71 | ret = new LegacyProvider(); 72 | (ret as Interfaces.IEntityGatewayClient).Register(this as IEntityGateway, clientThreadId); 73 | 74 | return ret; 75 | } 76 | 77 | void IDisposable.Dispose() 78 | { 79 | var contexts = _map.Clear(); 80 | var builder = new AggregateExceptionBuilder("Errors encountered while disposing DbContext objects"); 81 | 82 | foreach(var it in contexts) 83 | { 84 | try 85 | { 86 | (it as IDisposable).Dispose(); 87 | } 88 | catch(Exception ex) 89 | { 90 | builder.Add(ex); 91 | } 92 | } 93 | 94 | if (builder.HasErrors) 95 | throw builder.ToAggregateException(); 96 | } 97 | 98 | DbSet IEntityGateway.Set() 99 | { 100 | return (this as IEntityGateway).Context.Set(); 101 | } 102 | 103 | ObjectContext IEntityGateway.ObjectContext 104 | { 105 | get 106 | { 107 | ObjectContext ret = null; 108 | var adapter = (this as IEntityGateway).Context as IObjectContextAdapter; 109 | if (adapter != null) 110 | ret = adapter.ObjectContext; 111 | return ret; 112 | } 113 | } 114 | 115 | DbContext IEntityGateway.Context 116 | { 117 | get 118 | { 119 | var value = _map[Thread.CurrentThread.ManagedThreadId] as DbContext; 120 | 121 | return value; 122 | } 123 | } 124 | 125 | private DbContext CreateDbContext() 126 | { 127 | Contract.Ensures(Contract.Result() != null); 128 | 129 | DbContext ret = null; 130 | var builder = new EntityConnectionStringBuilder 131 | { 132 | ProviderConnectionString = KConnectionParameters.connection, 133 | Metadata = KConnectionParameters.modelResource, 134 | Provider = KConnectionParameters.provider 135 | }; 136 | ret = new DbContext(builder.ConnectionString); 137 | 138 | if (ret.Database.Connection.State != System.Data.ConnectionState.Open) 139 | ret.Database.Connection.Open(); 140 | 141 | return ret; 142 | } 143 | 144 | void IEntityGateway.Save() 145 | { 146 | try 147 | { 148 | (this as IEntityGateway).Context.SaveChanges(); 149 | } 150 | catch (Exception ex) 151 | { 152 | var innerException = ex; 153 | while (innerException.InnerException != null) 154 | innerException = innerException.InnerException; 155 | 156 | throw innerException; 157 | } 158 | } 159 | 160 | ObjectResult IDataManager.Execute(string sql, params object[] args) 161 | { 162 | var ret = default(ObjectResult); 163 | ret = (this as IEntityGateway).ObjectContext.ExecuteStoreQuery(sql, args); 164 | return ret; 165 | } 166 | 167 | #if DEBUG 168 | public override string ToString() 169 | { 170 | return $"_map: {_map.ToString()}"; 171 | } 172 | #endif 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /DataManager/Interfaces/ICleaner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GenericDataManager.Interfaces 4 | { 5 | public interface ICleaner:IDisposable 6 | { 7 | void Start(); 8 | } 9 | } -------------------------------------------------------------------------------- /DataManager/Interfaces/IContextMap.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using GenericDataManager.Common; 3 | using GenericDataManager.Interfaces; 4 | 5 | namespace GenericDataManager.Interfaces 6 | { 7 | public interface IContextMap 8 | { 9 | ContextProviderThreadPair this[int tid] { get; } 10 | 11 | int[] Keys { get; } 12 | ContextProviderThreadPair[] Values { get; } 13 | 14 | void Add(Thread th, IContextProvider provider); 15 | ContextProviderThreadPair[] Clear(); 16 | bool Has(Thread thread); 17 | IContextProvider Remove(int id); 18 | int Count { get; } 19 | } 20 | } -------------------------------------------------------------------------------- /DataManager/Interfaces/IDataManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | #if EF5 3 | using System.Data.EntityClient; 4 | using System.Data.Objects; 5 | #else 6 | using System.Data.Entity.Core.Objects; 7 | using System.Data.Entity.Core.EntityClient; 8 | #endif 9 | namespace GenericDataManager.Interfaces 10 | { 11 | /// 12 | /// Interface for teh data manager to acquire Entity writer and custom Sql executer 13 | /// 14 | public interface IDataManager : IDisposable 15 | { 16 | /// 17 | /// Retrives a custom repository based on the Entity specified as generic parameter 18 | /// 19 | /// The entity type for which the Repository pattern is required 20 | /// A specific repository class for the TEntity type that can be used to perform database operations. 21 | IEntityReaderWriter Get() where TEntity : class; 22 | 23 | /// 24 | /// Executes your custom sql with supplied parameters, if any. Do not use for Bulk operations 25 | /// 26 | /// 27 | /// the sql that you want to run directly 28 | /// any parameters to be supplied to the sql 29 | /// 30 | ObjectResult Execute(string sql, params object[] args); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /DataManager/Interfaces/IDataRepository.cs: -------------------------------------------------------------------------------- 1 | namespace GenericDataManager.Interfaces 2 | { 3 | public interface IDataRepository 4 | { 5 | IEntityReader GetReader() where TEntity : class; 6 | IEntityWriter GetWriter() where TEntity : class; 7 | IEntityReaderWriter Get() where TEntity : class; 8 | ISqlDirect Sql { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /DataManager/Interfaces/IDataRepositoryProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericDataManager.Interfaces 8 | { 9 | public interface IDataRepositoryProvider:IDisposable 10 | { 11 | IDataRepository Repository { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /DataManager/Interfaces/ISqlDirect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | 5 | namespace GenericDataManager.Interfaces 6 | { 7 | public interface ISqlDirect: IDisposable 8 | { 9 | T ExecuteScalar(string sql, Dictionary args = null); 10 | void ExecuteNonQuery(string sql, Dictionary args = null); 11 | IDataReader ExecuteReader(string sql, Dictionary args = null); 12 | long GetNumber(string sequenceName); 13 | } 14 | } -------------------------------------------------------------------------------- /DataManager/Interfaces/Interfaces.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | 5 | #if EF5 6 | using System.Data.EntityClient; 7 | using System.Data.Objects; 8 | #else 9 | using System.Data.Entity.Core.Objects; 10 | using System.Data.Entity.Core.EntityClient; 11 | #endif 12 | 13 | using System.Linq; 14 | using System.Linq.Expressions; 15 | 16 | namespace GenericDataManager.Interfaces 17 | { 18 | public interface IDestroyable 19 | { 20 | void Destroy(); 21 | } 22 | 23 | 24 | public interface IEntityGateway { 25 | 26 | ObjectContext ObjectContext {get; } 27 | DbContext Context { get; } 28 | 29 | DbSet Set() where TEntity: class; 30 | void Save(); 31 | 32 | void Release(int id); 33 | } 34 | 35 | /// 36 | /// An interface that must be implemented by the class that provides the IEntityReader or IEntityWriter interfaces. 37 | /// This interface helps the class to get get the db context, concurrency and reference counting provided by the manager 38 | /// 39 | public interface IEntityGatewayClient { 40 | /// 41 | /// A client class class to get itself registered with the manager 42 | /// 43 | /// An implementation (the class itself usually) that the manager uses to handle its instantiation and concurrency issues 44 | /// A constant key to be provided by the class. A GUID for instance 45 | /// duration for which a class can hold a lock if necessary 46 | void Register(IEntityGateway arg, int key); 47 | } 48 | 49 | 50 | public interface IContextProvider: IDisposable 51 | { 52 | DbContext DataContext { get; } 53 | ObjectContext ObjectContext { get; } 54 | void Release(IContextConsumer arg, string key); 55 | } 56 | public interface IContextConsumer: IDisposable 57 | { 58 | void Init(IContextProvider arg, string key); 59 | } 60 | 61 | 62 | public interface IEntityReader: IDisposable where TEntity:class 63 | { 64 | /// 65 | /// Retrieves a single record or 1st record if there are many, based on the expression provided 66 | /// 67 | /// Linq expression to be used to get a record 68 | /// record that satisfies the condition or the first record if there are many 69 | TEntity One(Expression> expr = null); 70 | /// 71 | /// Returns all records that satisfy a condition 72 | /// 73 | /// linq expression to retrieve the records 74 | /// a querable list of records 75 | IQueryable All(Expression> expr = null); 76 | /// 77 | /// Counts the number of records satifying a particular condition 78 | /// 79 | /// Linq expression to use to filter records 80 | /// returns the number of records that satisfied the condition 81 | long Count(Expression> expr = null); 82 | /// 83 | /// Checks if there is any record that satisfies the condtion 84 | /// 85 | /// linq expression to be used to verify 86 | /// 87 | bool Exists(Expression> expr = null); 88 | IEnumerable ReadOnly(Expression> expr = null); 89 | } 90 | public interface IEntityWriter : IDisposable where TEntity : class 91 | { 92 | /// 93 | /// Adds an entity to the database 94 | /// 95 | /// Entity record to be added 96 | void Add(TEntity arg); 97 | /// 98 | /// Adds a list of records to the database 99 | /// 100 | /// a list of records to be saved. 101 | void Add(IEnumerable arg); 102 | /// 103 | /// Saves the changes made to an entity 104 | /// 105 | /// record whose changes are to be saved 106 | void Update(TEntity arg); 107 | void Update(IEnumerable list); 108 | /// 109 | /// Updates a list of records that satisfy a particular expression[example: Update tbl Set tbl.X =?? Where tbl.Y = ? and tbl.Z = ?] 110 | /// 111 | /// Linq expression to be used 112 | /// Action which update the records 113 | void Update(Expression> expr, Action statement); 114 | /// 115 | /// Removes a record from the daatabase 116 | /// 117 | /// record to be removed 118 | void Delete(TEntity arg); 119 | void Delete(IEnumerable list); 120 | /// 121 | /// Removes records that satisfy a particular expression [eg: Delete tbl Where tbl.X=? and tbl.Y < ?] 122 | /// 123 | /// linq predicate that the records must satisfy for deletion 124 | void Delete(Expression> expr); 125 | } 126 | public interface IEntityReaderWriter : 127 | IEntityReader, 128 | IEntityWriter 129 | where TEntity : class 130 | { 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /DataManager/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Data.Engine")] 9 | [assembly: AssemblyDescription("This contains the generic data management operations for entities of EF model.")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DataManager")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1279a4ca-914a-4899-91ca-07b36915cc8d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.0.7.3")] 36 | [assembly: AssemblyFileVersion("2.0.3.3")] 37 | -------------------------------------------------------------------------------- /DataManager/Strategy/CleaningStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using GenericDataManager.Common; 5 | using GenericDataManager.Interfaces; 6 | using GenericDataManager.Providers; 7 | 8 | namespace GenericDataManager.Strategies 9 | { 10 | public class CleaningStrategyBase: 11 | IDisposable 12 | { 13 | protected readonly IContextMap _map; 14 | protected readonly ExecutionPolicy KPolicy; 15 | 16 | internal CleaningStrategyBase(IContextMap map, ExecutionPolicy policy) 17 | { 18 | KPolicy = policy; 19 | _map = map; 20 | } 21 | 22 | protected internal virtual void Clean() 23 | { 24 | } 25 | 26 | void IDisposable.Dispose() 27 | { 28 | var builder = new AggregateExceptionBuilder("Error while disposing the DbContext objects"); 29 | 30 | var keys = _map.Keys; //Keys will change so get a snapshot before starting to remove and use this snapshot 31 | foreach (var key in keys) 32 | { 33 | try 34 | { 35 | var provider = _map.Remove(key) as ContextProviderBase; 36 | if (provider.ConsumerCount > 0) 37 | builder.Add(new Exception($"Provider for thread {key} has {provider.ConsumerCount} consumer(s)")); 38 | provider.Dispose(); 39 | } 40 | catch(Exception ex) 41 | { 42 | builder.Add(ex); 43 | } 44 | } 45 | 46 | if (KPolicy.FinalDisposalBehaviour == ManagerDisposalStrategy.DisposeButThrowIfInUse && builder.HasErrors) 47 | throw builder.ToAggregateException(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /DataManager/Strategy/RemoveLeastRecentlyUsed.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using GenericDataManager.Common; 5 | using GenericDataManager.Interfaces; 6 | using GenericDataManager.Providers; 7 | 8 | namespace GenericDataManager.Strategies 9 | { 10 | public class RemoveLeastRecentlyUsed : 11 | CleaningStrategyBase 12 | { 13 | readonly TimeSpan _minAge; 14 | Func IsOlder => (age) => TimeSpan.Compare(_minAge, age) < 0; 15 | 16 | internal RemoveLeastRecentlyUsed(IContextMap map, ExecutionPolicy policy) : base(map, policy) 17 | { 18 | _minAge = TimeSpan.FromSeconds(10); 19 | _minAge = policy.MinimumAge; 20 | } 21 | 22 | protected internal override void Clean() 23 | { 24 | var values = _map.Values; 25 | var leastUsed = TimeSpan.Zero; 26 | 27 | var dispoablePairs = new List(); 28 | foreach (var pair in values) 29 | { 30 | var provider = pair.Provider as ContextProviderWithAge; 31 | if (provider != null) 32 | { 33 | if (provider.ConsumerCount > 0) 34 | { 35 | if (IsOlder(provider.LastUsed)) 36 | dispoablePairs.Add(pair); 37 | } 38 | else 39 | dispoablePairs.Add(pair); 40 | 41 | } 42 | } 43 | 44 | var keys = dispoablePairs.Select(x => x.Thread.ManagedThreadId).ToList(); 45 | foreach (var key in keys) 46 | { 47 | var tmp = _map[key].Provider as ContextProviderWithAge; 48 | if (tmp != null && IsOlder(tmp.LastUsed)) 49 | { 50 | var disposable = _map.Remove(key); 51 | if(disposable !=null) 52 | disposable.Dispose(); 53 | } 54 | 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /DataManager/Strategy/RemoveOnlyWhenThreadIsDead.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using GenericDataManager.Common; 3 | using GenericDataManager.Interfaces; 4 | 5 | namespace GenericDataManager.Strategies 6 | { 7 | public class RemoveOnlyWhenThreadIsDead : 8 | CleaningStrategyBase 9 | { 10 | internal RemoveOnlyWhenThreadIsDead(IContextMap map, ExecutionPolicy policy) : base(map, policy) { } 11 | 12 | protected internal override void Clean() 13 | { 14 | var keys = _map.Keys; 15 | foreach (var key in keys) 16 | { 17 | var pair = _map[key]; 18 | if (!pair.Thread.IsAlive) 19 | { 20 | _map.Remove(key); 21 | var disposable = pair.Provider as IDisposable; 22 | if (disposable != null) 23 | disposable.Dispose(); 24 | } 25 | 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /DataManager/Strategy/RemoveUnused.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using GenericDataManager.Common; 5 | using GenericDataManager.Interfaces; 6 | using GenericDataManager.Providers; 7 | 8 | namespace GenericDataManager.Strategies 9 | { 10 | public class RemoveUnused : 11 | CleaningStrategyBase 12 | { 13 | internal RemoveUnused(IContextMap map, ExecutionPolicy policy) : base(map, policy) { } 14 | 15 | protected internal override void Clean() 16 | { 17 | foreach (var key in _map.Keys) 18 | { 19 | var provider = _map[key].Provider as ContextProviderBase; 20 | if (provider!=null && provider.ConsumerCount == 0) 21 | { 22 | _map.Remove(key); 23 | provider.Dispose(); 24 | } 25 | } 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /DataManager/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![1475334088_database.png](https://s15.postimg.org/e3e6com23/1475334088_database.png)](https://postimg.org/image/vgogrjhd3/) 2 | # GenericDataManager 3 | ### Release Notes for version 1.5.5 4 | - Fixed: sometimes the QuickLock is already in locked state on creation from worker threads 5 | - Fixed: "Cannot start a new transaction" on DbContext when multiple threads are involved 6 | - Fixed: "There is already an open DataReader" when one thread is iterating over a list and other threads try to access 7 | - Fixed: DataManager correctly keeps track of DbContexts with the threads 8 | - Changed: DataManager uses ConnectionParameters struct for initialization rather than multiple parameters 9 | - Changed: DataManager throws AggregateException once when disposing off the DbContexts rather than stopping at the 1st exception 10 | - Fixed: multiple threads can simaltaneously access database without locking each other often and throwing TimeoutExpired exception 11 | 12 | ### Features requested and planned for next releases 13 | - Separate implementations of IEntityReader & IEntityWriter 14 | - ability to use Repositories without calling dispose 15 | - Ability to provide custom implementations for IContextConsumer and IContextProvider 16 | - Events by data manager 17 | 18 | _______ 19 | Please report the features you want or issues you encounter, your feedback means alot, [Contact me](mailto:suheylz@hotmail.com) if you have any queries 20 | _______ 21 | ## Notes 22 | Generic data manager is a thread safe IUnitOfWork repository tailered for your entities and takes care of all the plumbing so that you only concentrate on the database design and using that data. How to fetch it, common functions for manipulating the data, handiong the DbContexts, thread synchronization for DB calls, properly initializing and cleaning up everything ... well! forget about all that. just provide your model name and plain old simple connection to your database and enjoy the beer! DataManager will take care of 23 | - Create per thread DbContexts 24 | - Properly initialize and dispose them 25 | - Provides you the repository for each entity you require and totally tailored for it 26 | - Takes care of all the retrieval and saving of the data 27 | - In case of errors, it tries to give you the actual errors returned by the database rather than the usual *"Something Horrendeous Happend (which we don't care about). Keep seeing the InnerException for details ( and enjoy the rest of your day admiring how deep InnerException goes!)"* 28 | - if you forget to properly dispose any of the repositories, the data manager also takes care of that 29 | - gives you a functional or LINQy way so you are more concentrated on WHAT to do rather than HOW to do *(See Update() and Delete() variants)* 30 | 31 | So it gives you all the EntityFramework benefits without you using the EntityFramework directly and tries to do even more. All it asks you is provide a simple connection string in simple english [ConnectionStrings.com](www.connectionstrings.com) and only the name of your model. The data manager will build the rest of the connection string itself and creates the contexts per thread. You can safely delete the context from your entities model. It is not needed at all. Here is how you would use the DataManager. 32 | 33 | ### How to use it? 34 | - Use the nuget package [GenericDataManager](https://www.nuget.org/packages/GenericDataManager) to install it OR 35 | - Use the command `PM> Install-Package GenericDataManager` from package console OR 36 | - Download the source I have placed here and compile it yourself *(only if you have a lot of free time :) )* 37 | 38 | ### Sample Usage 39 | ```csharp 40 | // See! no convoluted connection string "metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider ....." 41 | var connection = new ConnectionParameters( 42 | "Server=myServer; Database=myDataBase; User Id=myuserName; Password=myPassword;", 43 | "MyModel" 44 | ); 45 | 46 | var manager = new DataManager.Core.Manager(connection); // no csdl or similar extension 47 | 48 | // Suppose you have an Entity Person. Here's how you would use it 49 | using(var repository = manager.Get()) 50 | { 51 | Console.WriteLine($"There are {repository.Count(x=>x.Age==20)} persons who are 20 years old"); 52 | 53 | //Now update all of them with a comment. note that you are not iterating over a list of persons 54 | repository.Update(x=>x.Age==20, x=>x.Notes = "We got ya"); 55 | 56 | //Delete all below 10. See! you only supply the predicate and tell it what to do. Functional style Eh? 57 | repository.Delete(x=>x.Age=<10); 58 | 59 | } // as soon as Dispose is called on repository the DataManager will take care of the rest. 60 | ``` 61 | ### How is it different 62 | The Data Manager keeps a Map that holds all the Repositories. if the requested repository for that Entity type is already in the map, it reference counts it and returns so the same Repository for that Entity is shared across different requests. If the repository is not there, The DataManager creates ones and returns the instance. The operations are thread safe unless you start tossing around entities from one thread to another, but worry not. Plan are underway to get around this limitation, for future versions 63 | 64 | ### Performance 65 | I'm in the process of updating unit tests and gathering some performance metrics. it will take a while. 66 | 67 | ### QuickLock 68 | As a utility class, Quicklock provides extremely performant inter thread synchronization. You can use it instead of C#’s `lock` keyword which internally uses Monitor and try/catch/finally. It uses Interlocked.Exchange methods to provide the functionality. If the lock cannot be acquired for a certain time it throws the TimeoutException. Here is how you would use: 69 | 70 | ```csharp 71 | var qlock = new QuickLock(TimeSpan.FromSeconds(30)); //wait for 30 seconds after which throw exception 72 | int data = 20; //our shared data 73 | 74 | private void FuncA() 75 | { 76 | for(int i =0; i<30; i++) 77 | { 78 | qlock.Lock(); 79 | data = 20 + i; 80 | qlock.Unlock(); 81 | } 82 | } 83 | 84 | private void FuncB() 85 | { 86 | for(int i =0; i<30; i++) 87 | { 88 | qlock.Lock(); 89 | data = 20%(i+1); 90 | qlock.Unlock(); 91 | } 92 | } 93 | ``` 94 | *I’m omitting the actual thread creation and stuff but it already gives you the idea of how to use it.* 95 | 96 | --------------------------------------------------------------------- 97 | ## Important Interfaces 98 | ### IEntityWriter 99 | Provides functions that change the state of the database by adding, changing or removing the data. 100 | *Currently the data manager does not provide any implementation for this interface. See IEntityReaderWriter below* 101 | 102 | #### Single Record Commands 103 | 104 | | Functions | Notes | 105 | |:-----------------------|:---------------------------------| 106 | | Add(TEntity) | Adds an entitiy to the database | 107 | | Delete(TEntity expr) | Deletes an entitiy from the database| 108 | | Update(TEntity arg) | Updates an entitiy into the database | 109 | 110 | 111 | #### Bulk Commands 112 | 113 | | Functions | Notes | 114 | |:----------|:-------------| 115 | | Add(IEnumerable<TEntity> list) | Adds a list of entities to the database | 116 | 117 | 118 | #### Bulk Commands LINQ based 119 | | Functions | Notes | 120 | |:----------|:-------------| 121 | | Update(Expression<Func<TEntity, bool>> expr, Action<TEntity> statement) | Specify a linq expression and an action, the function is equivalent to Update - Where | 122 | | Delete(Expression<Func<TEntity, bool>> expr) | Deletes entities from the database that match the expression you specify| 123 | 124 | 125 | ### IEntityReader 126 | Provies queries that do not change the state of the database, that is, provides functions that only retrieve data but cannot alter it. *Currently the data manager does not provide any implementation for this interface. See IEntityReaderWriter below* 127 | `Queries` 128 | 129 | |Functions |Returns |Notes | 130 | |--- |--- |--- | 131 | |Exists(Expression<Func<TEntity, bool>> expr) | bool | true if at least 1 entity satisfies the expression | 132 | |All(Expression<Func<TEntity, bool>> expr) | IQueryable| Linq Where() eqvivalent | 133 | |Count(Expression<Func<TEntity, bool>> expr)|long |Linq Count() with expression speciying the criteria | 134 | |One(Expression<Func<TEntity, bool>> expr) | TEntity| returns a single record, if there are many then only the first one of the list| 135 | 136 | ### IEntityReaderWriter: IEntityReader, IEntityWriter 137 | The data manager returns only this interface implementation so you get all the queries and commands mentioned above. Separate reader and writer interface implementations are planned for future versions so stay tuned. 138 | -------------------------------------------------------------------------------- /Samples/My First App/My First App.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E56E741B-E75E-4ED5-9D61-E45BEE60314F} 8 | Exe 9 | Properties 10 | MyFirstApp 11 | My First App 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | false 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | 38 | 39 | 40 | ..\..\..\Common Repository\EntityFramework.SqlServer.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {1279a4ca-914a-4899-91ca-07b36915cc8d} 55 | DataManager 56 | 57 | 58 | {faea2539-5184-49c7-a8b3-13065d0f426d} 59 | Sample.Entities 60 | 61 | 62 | 63 | 64 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /Samples/My First App/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | // Minimum namespaces references for GenericDataManager 5 | using GenericDataManager; 6 | using GenericDataManager.Common; 7 | using GenericDataManager.Interfaces; 8 | 9 | // Entities are here in this namespace. 10 | // be sure to add a reference to [EntityFramework.SqlServer.dll] otherwise your model would not be loaded. 11 | using Model = Sample.Entities; 12 | 13 | 14 | // Before running this besure that you have your sql server (version 2005 or higher) is up and running. 15 | // Also create a new database or you can use any exisiting database. 16 | // Run the script "Sample Database Script.sql" to initialize the database with tables and sample data 17 | 18 | namespace MyFirstApp 19 | { 20 | class Program 21 | { 22 | const string KConnectionString = @"data source=;initial catalog=;integrated security=True;"; 23 | const string KModelName = @"Entities"; 24 | 25 | static void Main(string[] args) 26 | { 27 | // Step 1: Create the connection parameters with a connection string and 28 | var connection = new ConnectionParameters(KConnectionString, KModelName); 29 | 30 | // Step 2: Use the default policy 31 | var policy = new ExecutionPolicy(); 32 | 33 | // Step 3: Create the manager and pass the connection and policy 34 | IDataRepositoryProvider manager = new DataManagerWithPolicy(connection, policy); 35 | 36 | // Step 4: Create the readonly repository for an entity "Employee" 37 | // using disposes the repository. It is a good practice to dispose the repository when finished 38 | using(var repository = manager.Repository.GetReader()) 39 | { 40 | // Step 5: Get the emmployees "SELECT TOP 3 * FROM [Employee]" 41 | var list = repository.All().Take(3).ToList(); 42 | 43 | // Step 6: Print the data 44 | foreach(var emp in list) 45 | { 46 | Console.WriteLine($"Id: {emp.ID} Name: {emp.FullName} Department: {emp.Department.Name} Email:{emp.Email}"); 47 | } 48 | } // The repository disposed here 49 | 50 | manager.Dispose(); // Dispose the manager now. 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Samples/Polly and Molly/Polly and Molly.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {443115D1-2451-46FA-9493-B0B874529CA7} 8 | Exe 9 | Properties 10 | Polly_n_Molly 11 | Polly and Molly 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | 39 | ..\..\..\Common Repository\EntityFramework.SqlServer.dll 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {1279a4ca-914a-4899-91ca-07b36915cc8d} 52 | DataManager 53 | 54 | 55 | {faea2539-5184-49c7-a8b3-13065d0f426d} 56 | Sample.Entities 57 | 58 | 59 | 60 | 61 | 62 | 63 | 70 | -------------------------------------------------------------------------------- /Samples/Polly and Molly/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading; 4 | 5 | // Minimum namespaces references for GenericDataManager 6 | using GenericDataManager; 7 | using GenericDataManager.Common; 8 | using GenericDataManager.Interfaces; 9 | 10 | // Entities are here in this namespace. 11 | // be sure to add a reference to [EntityFramework.SqlServer.dll] otherwise your model would not be loaded. 12 | using Model = Sample.Entities; 13 | 14 | 15 | // Before running this besure that you have your sql server (version 2005 or higher) is up and running. 16 | // Also create a new database or you can use any exisiting database. 17 | // Run the script "Sample Database Script.sql" to initialize the database with tables and sample data 18 | 19 | namespace Polly_and_Molly 20 | { 21 | class Program 22 | { 23 | const string KConnectionString = @"data source=;initial catalog=;integrated security=True;"; 24 | const string KModelName = @"Entities"; 25 | 26 | static void Main(string[] args) 27 | { 28 | // Step 1: Create the connection parameters with a connection string and 29 | var connection = new ConnectionParameters(KConnectionString, KModelName); 30 | 31 | // Step 2: Use the default policy 32 | var policy = new ExecutionPolicy(); 33 | 34 | // Step 3: Create the manager and pass the connection and policy 35 | IDataRepositoryProvider manager = new DataManagerWithPolicy(connection, policy); 36 | 37 | 38 | //Step 4: Here is polly, uses the same manager, gets ids of employee alphabetically sorted 39 | // adds the note and update them 40 | var polly = new Thread(() => { 41 | using (var rep = manager.Repository.Get()) 42 | { 43 | var ids = rep.All().OrderBy(x=>x.FullName).Select(x => x.ID).ToList(); 44 | 45 | foreach(var id in ids) 46 | { 47 | var emp = rep.One(x => x.ID == id); 48 | emp.Notes += "Polly touched you..."; 49 | rep.Update(emp); 50 | Console.WriteLine($"Polly touched {emp.FullName}"); 51 | } 52 | } 53 | }); 54 | 55 | //Step 5: Here is molly, uses the same manager, gets ids of employee alphabetically reverse order 56 | // adds the note and update them. at the middle record they both meet. 57 | var molly = new Thread(() => { 58 | using (var rep = manager.Repository.Get()) 59 | { 60 | var ids = rep.All().OrderByDescending(x=>x.FullName).Select(x => x.ID).ToList(); 61 | 62 | foreach (var id in ids) 63 | { 64 | var emp = rep.One(x => x.ID == id); 65 | emp.Notes += "Molly touched you..."; 66 | rep.Update(emp); 67 | Console.WriteLine($"Molly touched {emp.FullName}"); 68 | } 69 | } 70 | }); 71 | 72 | 73 | //Step 6: Now we start polly and molly 74 | polly.Start(); 75 | molly.Start(); 76 | 77 | // Step 7: Wait for the polly and molly to end 78 | polly.Join(); 79 | molly.Join(); 80 | 81 | 82 | //Step 8: Dispose manager 83 | manager.Dispose(); 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /Samples/Sample Database Script.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuheylZ/GenericDataManager/6fa8bd6da2dd7187dfde213f86bbcd4aba8d97a2/Samples/Sample Database Script.sql -------------------------------------------------------------------------------- /Samples/Sample.Entities/App.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Samples/Sample.Entities/Department.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 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 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace Sample.Entities 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class Department 16 | { 17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 18 | public Department() 19 | { 20 | this.Employees = new HashSet(); 21 | } 22 | 23 | public long Id { get; set; } 24 | public string Name { get; set; } 25 | public string Notes { get; set; } 26 | 27 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 28 | public virtual ICollection Employees { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Samples/Sample.Entities/Employee.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 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 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace Sample.Entities 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class Employee 16 | { 17 | public int ID { get; set; } 18 | public string FullName { get; set; } 19 | public string Email { get; set; } 20 | public string NIC { get; set; } 21 | public string Notes { get; set; } 22 | public Nullable DepartmentId { get; set; } 23 | 24 | public virtual Department Department { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Samples/Sample.Entities/Entities.Designer.cs: -------------------------------------------------------------------------------- 1 | // T4 code generation is enabled for model 'F:\Projects\GenericDataManager\Samples\Sample.Entities\Entities.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...'. -------------------------------------------------------------------------------- /Samples/Sample.Entities/Entities.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 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 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | -------------------------------------------------------------------------------- /Samples/Sample.Entities/Entities.edmx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /Samples/Sample.Entities/Entities.edmx.diagram: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Samples/Sample.Entities/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Sample.Entities")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Sample.Entities")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("faea2539-5184-49c7-a8b3-13065d0f426d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Samples/Sample.Entities/Sample.Entities.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FAEA2539-5184-49C7-A8B3-13065D0F426D} 8 | Library 9 | Properties 10 | Sample.Entities 11 | Sample.Entities 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | ..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll 38 | True 39 | 40 | 41 | ..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll 42 | True 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Entities.tt 58 | 59 | 60 | Entities.tt 61 | 62 | 63 | True 64 | True 65 | Entities.tt 66 | 67 | 68 | True 69 | True 70 | Entities.edmx 71 | 72 | 73 | 74 | 75 | 76 | EntityModelCodeGenerator 77 | Entities.Designer.cs 78 | 79 | 80 | 81 | 82 | Designer 83 | 84 | 85 | Entities.edmx 86 | 87 | 88 | 89 | 90 | 91 | TextTemplatingFileGenerator 92 | Entities.edmx 93 | Entities.cs 94 | 95 | 96 | 97 | 98 | 99 | 100 | 107 | -------------------------------------------------------------------------------- /Samples/Sample.Entities/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /UnitTests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /UnitTests/Employee.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 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 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace UnitTests 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class Employee 16 | { 17 | public int ID { get; set; } 18 | public string FullName { get; set; } 19 | public string Email { get; set; } 20 | public string NIC { get; set; } 21 | public string Notes { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /UnitTests/Entities.Context.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 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 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace UnitTests 11 | { 12 | using System; 13 | using System.Data.Entity; 14 | using System.Data.Entity.Infrastructure; 15 | 16 | public partial class UnitTestEntities : DbContext 17 | { 18 | public UnitTestEntities() 19 | : base("name=UnitTestEntities") 20 | { 21 | } 22 | 23 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 24 | { 25 | throw new UnintentionalCodeFirstException(); 26 | } 27 | 28 | public DbSet Employees { get; set; } 29 | public DbSet People { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /UnitTests/Entities.Designer.cs: -------------------------------------------------------------------------------- 1 | // T4 code generation is enabled for model 'F:\Projects\GenericDataManager\UnitTests\Entities.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...'. -------------------------------------------------------------------------------- /UnitTests/Entities.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 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 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | -------------------------------------------------------------------------------- /UnitTests/Entities.edmx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /UnitTests/Entities.edmx.diagram: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /UnitTests/InitializeDatabase.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuheylZ/GenericDataManager/6fa8bd6da2dd7187dfde213f86bbcd4aba8d97a2/UnitTests/InitializeDatabase.sql -------------------------------------------------------------------------------- /UnitTests/Person.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 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 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace UnitTests 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class Person 16 | { 17 | public string FullName { get; set; } 18 | public string Email { get; set; } 19 | public string NIC { get; set; } 20 | public int id { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /UnitTests/PolicyManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Threading; 6 | using GenericDataManager; 7 | using GenericDataManager.Common; 8 | using GenericDataManager.Interfaces; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | namespace UnitTests 12 | { 13 | [TestClass] 14 | public class PolicyManager: TestBase 15 | { 16 | [TestMethod] 17 | public void SingleInsert() 18 | { 19 | using(var rep = manager.Repository.Get()) 20 | { 21 | var id = 5577; 22 | rep.Add(new Person { id = id, FullName = "Test User 1", Email = "testuser@email.com", NIC = "1232233344"}); 23 | var p = rep.One(x => x.id == id); 24 | if (p == null) 25 | throw new ApplicationException("could not insert"); 26 | rep.Delete(p); 27 | } 28 | } 29 | 30 | [TestMethod] 31 | public void MultipleInserts() 32 | { 33 | var list = new List(400); 34 | var delta = 3456; 35 | 36 | for(var i=0;i < list.Capacity; i++) 37 | { 38 | var tmpID = i + delta; 39 | var emp = new Employee 40 | { 41 | ID = tmpID, 42 | FullName = $"Test User {tmpID}", 43 | Email = "testuser@email.com", 44 | NIC = $"{tmpID}32987" 45 | }; 46 | list.Add(emp); 47 | } 48 | 49 | using(var rep = manager.Repository.GetWriter()) 50 | { 51 | rep.Add(list); 52 | } 53 | } 54 | 55 | [TestMethod] 56 | public void MultipleThreadsUpdate() 57 | { 58 | Func CreateThread = (threadName) => { 59 | Action task = () => 60 | { 61 | using (var rep = manager.Repository.Get()) 62 | { 63 | var list = rep.All().Select(x => x.ID).ToList(); 64 | foreach (var it in list) 65 | { 66 | var tmp = rep.One(x => x.ID == it); 67 | tmp.Notes = tmp.Notes + $"{Thread.CurrentThread.Name}.."; 68 | rep.Update(tmp); 69 | Thread.Sleep(500); 70 | } 71 | } 72 | }; 73 | 74 | var th = new Thread(() => task()); 75 | th.Name = threadName; 76 | return th; 77 | }; 78 | 79 | 80 | var threads = new List(10); 81 | for (var i = 1; i <= threads.Capacity; i++) 82 | threads.Add(CreateThread($"t{i}")); 83 | 84 | foreach (var it in threads) 85 | it.Start(); 86 | 87 | while (threads.Count(x => x.IsAlive) > 0) 88 | Thread.Sleep(5000); 89 | } 90 | 91 | [TestMethod] 92 | public void LengthyThreads() 93 | { 94 | Func CreateTurtleThread = (threadName) => { 95 | Action turtleTask = () => 96 | { 97 | using (var rep = manager.Repository.Get()) 98 | { 99 | var list = rep.All().Take(50).Select(x => x.ID).ToList(); 100 | foreach (var it in list) 101 | { 102 | var tmp = rep.One(x => x.ID == it); 103 | tmp.Notes = tmp.Notes + $"{Thread.CurrentThread.Name}.."; 104 | rep.Update(tmp); 105 | 106 | Thread.Sleep(1000); 107 | } 108 | } 109 | }; 110 | 111 | var th = new Thread(() => turtleTask()); 112 | th.Name = threadName; 113 | return th; 114 | }; 115 | 116 | var threads = new List(3); 117 | for (var i = 1; i <= threads.Capacity; i++) 118 | threads.Add(CreateTurtleThread($"turtle{i}")); 119 | 120 | foreach (var it in threads) 121 | it.Start(); 122 | 123 | 124 | while (threads.Count(x => x.IsAlive) > 0) 125 | Thread.Sleep(TimeSpan.FromMinutes(1)); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /UnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UnitTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("UnitTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("dee0fc66-adf2-4300-a5eb-2d7a6ef965c9")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.0.0.63")] 36 | [assembly: AssemblyFileVersion("2.0.0.63")] 37 | -------------------------------------------------------------------------------- /UnitTests/TestBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using GenericDataManager.Interfaces; 6 | using GenericDataManager; 7 | using System.Configuration; 8 | using GenericDataManager.Common; 9 | 10 | namespace UnitTests 11 | { 12 | /// 13 | /// Summary description for DataManagerTestBase 14 | /// 15 | [TestClass] 16 | public class TestBase 17 | { 18 | protected IDataRepositoryProvider manager; 19 | 20 | public TestBase() 21 | { 22 | } 23 | 24 | private TestContext testContextInstance; 25 | 26 | /// 27 | ///Gets or sets the test context which provides 28 | ///information about and functionality for the current test run. 29 | /// 30 | public TestContext TestContext 31 | { 32 | get 33 | { 34 | return testContextInstance; 35 | } 36 | set 37 | { 38 | testContextInstance = value; 39 | } 40 | } 41 | 42 | #region Additional test attributes 43 | // 44 | // You can use the following additional attributes as you write your tests: 45 | // 46 | // Use ClassInitialize to run code before running the first test in the class 47 | // [ClassInitialize()] 48 | // public static void MyClassInitialize(TestContext testContext) { } 49 | // 50 | // Use ClassCleanup to run code after all tests in a class have run 51 | // [ClassCleanup()] 52 | // public static void MyClassCleanup() { } 53 | // 54 | // Use TestInitialize to run code before running each test 55 | // [TestInitialize()] 56 | // public void MyTestInitialize() { } 57 | // 58 | // Use TestCleanup to run code after each test has run 59 | // [TestCleanup()] 60 | // public void MyTestCleanup() { } 61 | // 62 | #endregion 63 | 64 | [TestInitialize] 65 | public void Initialize() 66 | { 67 | var arg = new ConnectionParameters( 68 | ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString, 69 | ConfigurationManager.AppSettings["model"], 70 | 10); 71 | 72 | var policy = new ExecutionPolicy 73 | { 74 | PeriodicDisposalStrategy = Strategy.DisposeWhenNotInUse, 75 | FinalDisposalBehaviour = ManagerDisposalStrategy.DisposeButThrowIfInUse, 76 | HeartBeat = TimeSpan.FromSeconds(30) 77 | }; 78 | 79 | manager = new DataManagerWithPolicy(arg, policy); 80 | } 81 | 82 | [TestCleanup] 83 | public void CleanUp() 84 | { 85 | manager.Dispose(); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /UnitTests/UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {DEE0FC66-ADF2-4300-A5EB-2D7A6EF965C9} 7 | Library 8 | Properties 9 | UnitTests 10 | UnitTests 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | false 30 | 31 | 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE 36 | prompt 37 | 4 38 | false 39 | 40 | 41 | 42 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll 43 | True 44 | 45 | 46 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll 47 | True 48 | 49 | 50 | 51 | 52 | 53 | 3.5 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | False 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | Entities.tt 78 | 79 | 80 | True 81 | True 82 | Entities.Context.tt 83 | 84 | 85 | True 86 | True 87 | Entities.tt 88 | 89 | 90 | True 91 | True 92 | Entities.edmx 93 | 94 | 95 | Entities.tt 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | EntityModelCodeGenerator 104 | Entities.Designer.cs 105 | 106 | 107 | Entities.edmx 108 | 109 | 110 | 111 | 112 | 113 | {1279a4ca-914a-4899-91ca-07b36915cc8d} 114 | DataManager 115 | 116 | 117 | 118 | 119 | TextTemplatingFileGenerator 120 | Entities.edmx 121 | Entities.Context.cs 122 | 123 | 124 | TextTemplatingFileGenerator 125 | Entities.edmx 126 | Entities.cs 127 | 128 | 129 | Always 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | False 143 | 144 | 145 | False 146 | 147 | 148 | False 149 | 150 | 151 | False 152 | 153 | 154 | 155 | 156 | 157 | 158 | 165 | -------------------------------------------------------------------------------- /UnitTests/bin/Debug/UnitTests.dll.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /UnitTests/bin/Release/UnitTests.dll.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /UnitTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/Content/App.config.transform: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/Content/Web.config.transform: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/EntityFramework.4.3.1.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuheylZ/GenericDataManager/6fa8bd6da2dd7187dfde213f86bbcd4aba8d97a2/packages/EntityFramework.4.3.1/EntityFramework.4.3.1.nupkg -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/EF4.3on.NET4.5Readme.txt: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------------------------- 2 | Entity Framework 5 Recommended for .NET Framework 4.5 Projects 3 | ----------------------------------------------------------------------------------------- 4 | 5 | 6 | You have installed EF 4.3 in a project that targets .NET Framework 4.5. 7 | 8 | There are some known issues using EF 4.x in a .NET 4.5 project. 9 | 10 | 11 | We recommend installing a pre-release version of EF 5, which is designed to work with .NET 4.5 12 | 13 | 1) Open package manager console 14 | Tools -> Library Package Manager -> Package Manager Console 15 | 16 | 2) Use the following command to install the latest pre-release package 17 | Install-Package EntityFramework -IncludePreRelease 18 | 19 | 20 | 21 | ----------------------------------------------------------------------------------------- 22 | Known Issues with Entity Framework 4.x and .NET Framework 4.5 23 | ----------------------------------------------------------------------------------------- 24 | 25 | Entity Framework 4.1 thru 4.3 included additional data annotations in the 26 | System.ComponentModel.DataAnnotations namespace in the EntityFramework assembly. 27 | In .NET 4.5 these annotations were moved to be part of the .NET Framework in the 28 | System.ComponentModel.DataAnnotations.Schema namespace of the 29 | System.ComponentModel.DataAnnotations.dll assembly. If you are using EF 4.x and targeting 30 | .NET 4.5 this results in two data annotations with the same name in different assemblies. 31 | Because the annotations in the .NET Framework are in a different namespace we were not 32 | able to use type forwarding to avoid this conflict. 33 | 34 | It is possible to use EF 4.x on .NET 4.5 but we recommend using the latest pre-release 35 | version of EF 5. If you are not using the affected data annotations there is no impact 36 | on your code. If you are using the data annotations in a C# project you can use the extern 37 | modifier to ensure your code uses the annotations from EntityFramework.dll 38 | (http://msdn.microsoft.com/en-us/library/e59b22c5(v=VS.80).aspx). If you use the new 39 | annotations from the System.ComponentModel.DataAnnotations.dll assembly in .NET 4.5 40 | they will not be processed by Code First. 41 | 42 | The affected annotations are: 43 | - Column 44 | - ComplexType 45 | - DatabaseGenerated 46 | - DatabaseGeneratedOption 47 | - ForeignKey 48 | - InverseProperty 49 | - MaxLength 50 | - MinLength 51 | - NotMapped 52 | - Table 53 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/EntityFramework.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuheylZ/GenericDataManager/6fa8bd6da2dd7187dfde213f86bbcd4aba8d97a2/packages/EntityFramework.4.3.1/tools/EntityFramework.psd1 -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/EntityFramework.psm1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation. All rights reserved. 2 | 3 | $InitialDatabase = '0' 4 | 5 | $installPath = $args[0] 6 | $knownExceptions = @( 7 | 'System.Data.Entity.Migrations.Infrastructure.MigrationsException', 8 | 'System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException', 9 | 'System.Data.Entity.Migrations.Infrastructure.AutomaticDataLossException' 10 | ) 11 | 12 | <# 13 | .SYNOPSIS 14 | Enables Code First Migrations in a project. 15 | 16 | .DESCRIPTION 17 | Enables Migrations by scaffolding a migrations configuration class in the project. If the 18 | target database was created by an initializer, an initial migration will be created (unless 19 | automatic migrations are enabled via the EnableAutomaticMigrations parameter). 20 | 21 | .PARAMETER EnableAutomaticMigrations 22 | Specifies whether automatic migrations will be enabled in the scaffolded migrations configuration. 23 | If ommitted, automatic migrations will be disabled. 24 | 25 | .PARAMETER ProjectName 26 | Specifies the project that the scaffolded migrations configuration class will 27 | be added to. If omitted, the default project selected in package manager 28 | console is used. 29 | 30 | .PARAMETER Force 31 | Specifies that the migrations configuration be overwritten when running more 32 | than once for a given project. 33 | #> 34 | function Enable-Migrations 35 | { 36 | [CmdletBinding(DefaultParameterSetName = 'ProjectName')] 37 | param ( 38 | [alias("Auto")] 39 | [switch] $EnableAutomaticMigrations, 40 | [string] $ProjectName, 41 | [switch] $Force 42 | ) 43 | 44 | try 45 | { 46 | $commands = New-MigrationsCommandsNoConfiguration $ProjectName 47 | $commands.EnableMigrations($EnableAutomaticMigrations, $Force) 48 | } 49 | catch [Exception] 50 | { 51 | $exception = $_.Exception 52 | $exceptionType = $exception.GetType() 53 | 54 | if ($exceptionType.FullName -eq 'System.Data.Entity.Migrations.Design.ToolingException') 55 | { 56 | if ($knownExceptions -notcontains $exception.InnerType) 57 | { 58 | Write-Host $exception.InnerStackTrace 59 | } 60 | } 61 | elseif (!(Test-TypeInherits $exceptionType 'System.Data.Entity.Migrations.Infrastructure.MigrationsException')) 62 | { 63 | Write-Host $exception 64 | } 65 | 66 | throw $exception.Message 67 | } 68 | } 69 | 70 | <# 71 | .SYNOPSIS 72 | Scaffolds a migration script for any pending model changes. 73 | 74 | .DESCRIPTION 75 | Scaffolds a new migration script and adds it to the project. 76 | 77 | .PARAMETER Name 78 | Specifies the name of the custom script. 79 | 80 | .PARAMETER Force 81 | Specifies that the migration user code be overwritten when re-scaffolding an 82 | existing migration. 83 | 84 | .PARAMETER ProjectName 85 | Specifies the project that contains the migration configuration type to be 86 | used. If ommitted, the default project selected in package manager console 87 | is used. 88 | 89 | .PARAMETER StartUpProjectName 90 | Specifies the configuration file to use for named connection strings. If 91 | omitted, the specified project's configuration file is used. 92 | 93 | .PARAMETER ConfigurationTypeName 94 | Specifies the migrations configuration to use. If omitted, migrations will 95 | attempt to locate a single migrations configuration type in the target 96 | project. 97 | 98 | .PARAMETER ConnectionStringName 99 | Specifies the name of a connection string to use from the application's 100 | configuration file. 101 | 102 | .PARAMETER ConnectionString 103 | Specifies the the connection string to use. If omitted, the context's 104 | default connection will be used. 105 | 106 | .PARAMETER ConnectionProviderName 107 | Specifies the provider invariant name of the connection string. 108 | 109 | .PARAMETER IgnoreChanges 110 | Scaffolds an empty migration ignoring any pending changes detected in the current model. 111 | This can be used to create an initial, empty migration to enable Migrations for an existing 112 | database. N.B. Doing this assumes that the target database schema is compatible with the 113 | current model. 114 | 115 | #> 116 | function Add-Migration 117 | { 118 | [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')] 119 | param ( 120 | [parameter(Position = 0, 121 | Mandatory = $true)] 122 | [string] $Name, 123 | [switch] $Force, 124 | [string] $ProjectName, 125 | [string] $StartUpProjectName, 126 | [string] $ConfigurationTypeName, 127 | [parameter(ParameterSetName = 'ConnectionStringName')] 128 | [string] $ConnectionStringName, 129 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 130 | Mandatory = $true)] 131 | [string] $ConnectionString, 132 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 133 | Mandatory = $true)] 134 | [string] $ConnectionProviderName, 135 | [switch] $IgnoreChanges) 136 | 137 | try 138 | { 139 | $commands = New-MigrationsCommands $ProjectName $StartUpProjectName $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName 140 | $commands.AddMigration($Name, $Force, $IgnoreChanges) 141 | } 142 | catch [Exception] 143 | { 144 | $exception = $_.Exception 145 | $exceptionType = $exception.GetType() 146 | 147 | if ($exceptionType.FullName -eq 'System.Data.Entity.Migrations.Design.ToolingException') 148 | { 149 | if ($knownExceptions -notcontains $exception.InnerType) 150 | { 151 | Write-Host $exception.InnerStackTrace 152 | } 153 | } 154 | elseif (!(Test-TypeInherits $exceptionType 'System.Data.Entity.Migrations.Infrastructure.MigrationsException')) 155 | { 156 | Write-Host $exception 157 | } 158 | 159 | throw $exception.Message 160 | } 161 | } 162 | 163 | <# 164 | .SYNOPSIS 165 | Applies any pending migrations to the database. 166 | 167 | .DESCRIPTION 168 | Updates the database to the current model by applying pending migrations. 169 | 170 | .PARAMETER SourceMigration 171 | Only valid with -Script. Specifies the name of a particular migration to use 172 | as the update's starting point. If ommitted, the last applied migration in 173 | the database will be used. 174 | 175 | .PARAMETER TargetMigration 176 | Specifies the name of a particular migration to update the database to. If 177 | ommitted, the current model will be used. 178 | 179 | .PARAMETER Script 180 | Generate a SQL script rather than executing the pending changes directly. 181 | 182 | .PARAMETER Force 183 | Specifies that data loss is acceptable during automatic migration of the 184 | database. 185 | 186 | .PARAMETER ProjectName 187 | Specifies the project that contains the migration configuration type to be 188 | used. If ommitted, the default project selected in package manager console 189 | is used. 190 | 191 | .PARAMETER StartUpProjectName 192 | Specifies the configuration file to use for named connection strings. If 193 | omitted, the specified project's configuration file is used. 194 | 195 | .PARAMETER ConfigurationTypeName 196 | Specifies the migrations configuration to use. If omitted, migrations will 197 | attempt to locate a single migrations configuration type in the target 198 | project. 199 | 200 | .PARAMETER ConnectionStringName 201 | Specifies the name of a connection string to use from the application's 202 | configuration file. 203 | 204 | .PARAMETER ConnectionString 205 | Specifies the the connection string to use. If omitted, the context's 206 | default connection will be used. 207 | 208 | .PARAMETER ConnectionProviderName 209 | Specifies the provider invariant name of the connection string. 210 | #> 211 | function Update-Database 212 | { 213 | [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')] 214 | param ( 215 | [string] $SourceMigration, 216 | [string] $TargetMigration, 217 | [switch] $Script, 218 | [switch] $Force, 219 | [string] $ProjectName, 220 | [string] $StartUpProjectName, 221 | [string] $ConfigurationTypeName, 222 | [parameter(ParameterSetName = 'ConnectionStringName')] 223 | [string] $ConnectionStringName, 224 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 225 | Mandatory = $true)] 226 | [string] $ConnectionString, 227 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 228 | Mandatory = $true)] 229 | [string] $ConnectionProviderName) 230 | 231 | # TODO: If possible, convert this to a ParameterSet 232 | if ($SourceMigration -and !$script) 233 | { 234 | throw '-SourceMigration can only be specified with -Script.' 235 | } 236 | 237 | try 238 | { 239 | $commands = New-MigrationsCommands $ProjectName $StartUpProjectName $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName 240 | $commands.UpdateDatabase($SourceMigration, $TargetMigration, $Script, $Force) 241 | } 242 | catch [Exception] 243 | { 244 | $exception = $_.Exception 245 | $exceptionType = $exception.GetType() 246 | 247 | if ($exceptionType.FullName -eq 'System.Data.Entity.Migrations.Design.ToolingException') 248 | { 249 | if ($knownExceptions -notcontains $exception.InnerType) 250 | { 251 | Write-Host $exception.InnerStackTrace 252 | } 253 | } 254 | elseif (!(Test-TypeInherits $exceptionType 'System.Data.Entity.Migrations.Infrastructure.MigrationsException')) 255 | { 256 | Write-Host $exception 257 | } 258 | 259 | throw $exception.Message 260 | } 261 | } 262 | 263 | <# 264 | .SYNOPSIS 265 | Displays the migrations that have been applied to the target database. 266 | 267 | .DESCRIPTION 268 | Displays the migrations that have been applied to the target database. 269 | 270 | .PARAMETER ProjectName 271 | Specifies the project that contains the migration configuration type to be 272 | used. If ommitted, the default project selected in package manager console 273 | is used. 274 | 275 | .PARAMETER StartUpProjectName 276 | Specifies the configuration file to use for named connection strings. If 277 | omitted, the specified project's configuration file is used. 278 | 279 | .PARAMETER ConfigurationTypeName 280 | Specifies the migrations configuration to use. If omitted, migrations will 281 | attempt to locate a single migrations configuration type in the target 282 | project. 283 | 284 | .PARAMETER ConnectionStringName 285 | Specifies the name of a connection string to use from the application's 286 | configuration file. 287 | 288 | .PARAMETER ConnectionString 289 | Specifies the the connection string to use. If omitted, the context's 290 | default connection will be used. 291 | 292 | .PARAMETER ConnectionProviderName 293 | Specifies the provider invariant name of the connection string. 294 | #> 295 | function Get-Migrations 296 | { 297 | [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')] 298 | param ( 299 | [string] $ProjectName, 300 | [string] $StartUpProjectName, 301 | [string] $ConfigurationTypeName, 302 | [parameter(ParameterSetName = 'ConnectionStringName')] 303 | [string] $ConnectionStringName, 304 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 305 | Mandatory = $true)] 306 | [string] $ConnectionString, 307 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 308 | Mandatory = $true)] 309 | [string] $ConnectionProviderName) 310 | 311 | try 312 | { 313 | $commands = New-MigrationsCommands $ProjectName $StartUpProjectName $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName 314 | $commands.GetMigrations() 315 | } 316 | catch [Exception] 317 | { 318 | $exception = $_.Exception 319 | $exceptionType = $exception.GetType() 320 | 321 | if ($exceptionType.FullName -eq 'System.Data.Entity.Migrations.Design.ToolingException') 322 | { 323 | if ($knownExceptions -notcontains $exception.InnerType) 324 | { 325 | Write-Host $exception.InnerStackTrace 326 | } 327 | } 328 | elseif (!(Test-TypeInherits $exceptionType 'System.Data.Entity.Migrations.Infrastructure.MigrationsException')) 329 | { 330 | Write-Host $exception 331 | } 332 | 333 | throw $exception.Message 334 | } 335 | } 336 | 337 | function New-MigrationsCommandsNoConfiguration($ProjectName) 338 | { 339 | $project = Get-MigrationsProject $ProjectName 340 | 341 | Build-Project $project 342 | 343 | Load-EntityFramework 344 | 345 | try 346 | { 347 | return New-Object 'System.Data.Entity.Migrations.MigrationsCommands' @( 348 | $project, 349 | $project, 350 | $null, 351 | $null, 352 | $null, 353 | $null, 354 | $PSCmdlet ) 355 | } 356 | catch [System.Management.Automation.MethodInvocationException] 357 | { 358 | throw $_.Exception.InnerException 359 | } 360 | } 361 | 362 | function New-MigrationsCommands($ProjectName, $StartUpProjectName, $ConfigurationTypeName, $ConnectionStringName, $ConnectionString, $ConnectionProviderName) 363 | { 364 | $project = Get-MigrationsProject $ProjectName 365 | $startUpProject = Get-MigrationsStartUpProject $StartUpProjectName 366 | 367 | Build-Project $project 368 | Build-Project $startUpProject 369 | 370 | Load-EntityFramework 371 | 372 | try 373 | { 374 | return New-Object 'System.Data.Entity.Migrations.MigrationsCommands' @( 375 | $project, 376 | $startUpProject, 377 | $ConfigurationTypeName, 378 | $ConnectionStringName, 379 | $ConnectionString, 380 | $ConnectionProviderName, 381 | $PSCmdlet ) 382 | } 383 | catch [System.Management.Automation.MethodInvocationException] 384 | { 385 | throw $_.Exception.InnerException 386 | } 387 | } 388 | 389 | function Get-MigrationsProject($name) 390 | { 391 | if ($name) 392 | { 393 | return Get-SingleProject $name 394 | } 395 | 396 | $project = Get-Project 397 | 398 | Write-Verbose ('Using NuGet project ''' + $project.Name + '''.') 399 | 400 | return $project 401 | } 402 | 403 | function Get-MigrationsStartUpProject($name) 404 | { 405 | if ($name) 406 | { 407 | return Get-SingleProject $name 408 | } 409 | 410 | $startupProjectPaths = $DTE.Solution.SolutionBuild.StartupProjects 411 | 412 | if (!$startupProjectPaths) 413 | { 414 | throw 'No start-up project found. Please use the -StartupProject parameter.' 415 | } 416 | if ($startupProjectPaths.Length -gt 1) 417 | { 418 | throw 'More than one start-up project found. Please use the -StartUpProject parameter.' 419 | } 420 | 421 | $startupProjectPath = $startupProjectPaths[0] 422 | 423 | if (!(Split-Path -IsAbsolute $startupProjectPath)) 424 | { 425 | $solutionPath = Split-Path $DTE.Solution.Properties.Item('Path').Value 426 | $startupProjectPath = Join-Path $solutionPath $startupProjectPath -Resolve 427 | } 428 | 429 | $startupProject = $DTE.Solution.Projects | ?{ 430 | $fullName = $_.FullName 431 | 432 | if ($fullName -and $fullName.EndsWith('\')) 433 | { 434 | $fullName = $fullName.Substring(0, $fullName.Length - 1) 435 | } 436 | 437 | return $fullName -eq $startupProjectPath 438 | } 439 | 440 | Write-Verbose ('Using StartUp project ''' + $startupProject.Name + '''.') 441 | 442 | return $startupProject 443 | } 444 | 445 | function Get-SingleProject($name) 446 | { 447 | $project = Get-Project $name 448 | 449 | if ($project -is [array]) 450 | { 451 | throw "More than one project '$name' was found. Specify the full name of the one to use." 452 | } 453 | 454 | return $project 455 | } 456 | 457 | function Load-EntityFramework() 458 | { 459 | [System.AppDomain]::CurrentDomain.SetShadowCopyFiles() 460 | [System.Reflection.Assembly]::LoadFrom((Join-Path $installPath 'lib\net40\EntityFramework.dll')) | Out-Null 461 | [System.Reflection.Assembly]::LoadFrom((Join-Path $installPath 'tools\EntityFramework.PowerShell.dll')) | Out-Null 462 | } 463 | 464 | function Build-Project($project) 465 | { 466 | $configuration = $DTE.Solution.SolutionBuild.ActiveConfiguration.Name 467 | 468 | $DTE.Solution.SolutionBuild.BuildProject($configuration, $project.UniqueName, $true) 469 | 470 | if ($DTE.Solution.SolutionBuild.LastBuildInfo) 471 | { 472 | throw 'The project ''' + $project.Name + ''' failed to build.' 473 | } 474 | } 475 | 476 | function Test-TypeInherits($type, $baseTypeName) 477 | { 478 | if ($type.FullName -eq $baseTypeName) 479 | { 480 | return $true 481 | } 482 | 483 | $baseType = $type.BaseType 484 | 485 | if ($baseType) 486 | { 487 | return Test-TypeInherits $baseType $baseTypeName 488 | } 489 | 490 | return $false 491 | } 492 | 493 | Export-ModuleMember @( 'Enable-Migrations', 'Add-Migration', 'Update-Database', 'Get-Migrations' ) -Variable 'InitialDatabase' 494 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/init.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | if ([System.AppDomain]::CurrentDomain.GetAssemblies() | ?{ $_.GetName().Name -eq 'EntityFramework' }) 4 | { 5 | Write-Warning 'There is already a version of EntityFramework.dll loaded. You may need to restart Visual Studio for the commands to work properly.' 6 | } 7 | 8 | if (Get-Module | ?{ $_.Name -eq 'EntityFramework' }) 9 | { 10 | Remove-Module 'EntityFramework' 11 | } 12 | 13 | Import-Module (Join-Path $toolsPath 'EntityFramework.psd1') -ArgumentList $installPath 14 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | $invoker = @" 4 | public class ConnectionFactoryConfiguratorInvoker 5 | { 6 | public static void Invoke(string assemblyPath, object project) 7 | { 8 | var appDomain = System.AppDomain.CreateDomain( 9 | "EntityFramework.PowerShell", 10 | null, 11 | new System.AppDomainSetup { ShadowCopyFiles = "true" }); 12 | 13 | appDomain.CreateInstanceFrom( 14 | assemblyPath, 15 | "System.Data.Entity.ConnectionFactoryConfig.ConnectionFactoryConfigurator", 16 | false, 17 | 0, 18 | null, 19 | new object[] { project }, 20 | null, 21 | null); 22 | 23 | System.AppDomain.Unload(appDomain); 24 | } 25 | } 26 | "@ 27 | 28 | $version = (new-object System.Runtime.Versioning.FrameworkName($project.Properties.Item("TargetFrameworkMoniker").Value)).Version 29 | 30 | if ($version -ge (new-object System.Version(4, 5))) 31 | { 32 | $dte.ItemOperations.OpenFile((Join-Path $toolsPath 'EF4.3on.NET4.5Readme.txt')) 33 | } 34 | 35 | Add-Type -TypeDefinition $invoker 36 | [ConnectionFactoryConfiguratorInvoker]::Invoke((Join-Path $toolsPath "EntityFramework.PowerShell.dll"), $project) 37 | -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/Content/App.config.transform: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/Content/Web.config.transform: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/EntityFramework.5.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuheylZ/GenericDataManager/6fa8bd6da2dd7187dfde213f86bbcd4aba8d97a2/packages/EntityFramework.5.0.0/EntityFramework.5.0.0.nupkg -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/tools/EntityFramework.PS3.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuheylZ/GenericDataManager/6fa8bd6da2dd7187dfde213f86bbcd4aba8d97a2/packages/EntityFramework.5.0.0/tools/EntityFramework.PS3.psd1 -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/tools/EntityFramework.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuheylZ/GenericDataManager/6fa8bd6da2dd7187dfde213f86bbcd4aba8d97a2/packages/EntityFramework.5.0.0/tools/EntityFramework.psd1 -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/tools/Redirect.VS11.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/tools/Redirect.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/tools/about_EntityFramework.help.txt: -------------------------------------------------------------------------------- 1 | TOPIC 2 | about_EntityFramework 3 | 4 | SHORT DESCRIPTION 5 | Provides information about Entity Framework commands. 6 | 7 | LONG DESCRIPTION 8 | This topic describes the Entity Framework commands. Entity Framework is 9 | Microsoft's recommended data access technology for new applications. 10 | 11 | 12 | The following Entity Framework cmdlets are included. 13 | 14 | Cmdlet Description 15 | ----------------- --------------------------------------------------- 16 | Enable-Migrations Enables Code First Migrations in a project. 17 | 18 | Add-Migration Scaffolds a migration script for any pending model 19 | changes. 20 | 21 | Update-Database Applies any pending migrations to the database. 22 | 23 | Get-Migrations Displays the migrations that have been applied to 24 | the target database. 25 | 26 | SEE ALSO 27 | Enable-Migrations 28 | Add-Migration 29 | Update-Database 30 | Get-Migrations 31 | -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/tools/init.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | $importedModule = Get-Module | ?{ $_.Name -eq 'EntityFramework' } 4 | 5 | if ($PSVersionTable.PSVersion -ge (New-Object Version @( 3, 0 ))) 6 | { 7 | $thisModuleManifest = 'EntityFramework.PS3.psd1' 8 | } 9 | else 10 | { 11 | $thisModuleManifest = 'EntityFramework.psd1' 12 | } 13 | 14 | $thisModule = Test-ModuleManifest (Join-Path $toolsPath $thisModuleManifest) 15 | $shouldImport = $true 16 | 17 | if ($importedModule) 18 | { 19 | if ($importedModule.Version -le $thisModule.Version) 20 | { 21 | Remove-Module EntityFramework 22 | } 23 | else 24 | { 25 | $shouldImport = $false 26 | } 27 | } 28 | 29 | if ($shouldImport) 30 | { 31 | Import-Module $thisModule 32 | } 33 | 34 | # SIG # Begin signature block 35 | # MIIaSAYJKoZIhvcNAQcCoIIaOTCCGjUCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB 36 | # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR 37 | # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU4JbMotbKQrAO4s/cceCMbJQG 38 | # 482gghUtMIIEoDCCA4igAwIBAgIKYRnMkwABAAAAZjANBgkqhkiG9w0BAQUFADB5 39 | # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk 40 | # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSMwIQYDVQQDExpN 41 | # aWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQTAeFw0xMTEwMTAyMDMyMjVaFw0xMzAx 42 | # MTAyMDMyMjVaMIGDMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ 43 | # MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u 44 | # MQ0wCwYDVQQLEwRNT1BSMR4wHAYDVQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24w 45 | # ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDuW759ESTjhgbgZv9ItRe9 46 | # AuS0DDLwcj59LofXTqGxp0Mv92WeMeEyMUWu18EkhCHXLrWEfvo101Mc17ZRHk/O 47 | # ZrnrtwwC/SlcraiH9soitNW/CHX1inCPY9fvih7pj0MkZFrTh32QbTusds1XNn3o 48 | # vBBWrJjwiV0uZMavJgleHmMV8T2/Fo+ZiALDMLfBC2AfD3LM1reoNRKGm6ELCuaT 49 | # W476VJzB8xlfQo0Snx0/kLcnE4MZMoId89mH1CGyPKK2B0/XJKrujfWz2fr5OU+n 50 | # 6fKvWVL03EGbLxFwY93q3qrxbSEEEFMzu7JPxeFTskFlR2439rzpmxZBkWsuWzDD 51 | # AgMBAAGjggEdMIIBGTATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUG1IO 52 | # 8xEqt8CJwxGBPdSWWLmjU24wDgYDVR0PAQH/BAQDAgeAMB8GA1UdIwQYMBaAFMsR 53 | # 6MrStBZYAck3LjMWFrlMmgofMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwu 54 | # bWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY0NvZFNpZ1BDQV8wOC0z 55 | # MS0yMDEwLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93 56 | # d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljQ29kU2lnUENBXzA4LTMxLTIw 57 | # MTAuY3J0MA0GCSqGSIb3DQEBBQUAA4IBAQClWzZsrU6baRLjb4oCm2l3w2xkciiI 58 | # 2T1FbSwYe9QoLxPiWWobwgs0t4r96rmU7Acx5mr0dQTTp9peOgaeEP2pDb2cUUNv 59 | # /2eUnOHPfPAksDXMg13u2sBvNknAWgpX9nPhnvPjCEw7Pi/M0s3uTyJw9wQfAqZL 60 | # m7iPXIgONpRsMwe4qa1RoNDC3I4iEr3D34LXVqH33fClIFcQEJ3urIZ0bHGbwfDy 61 | # wnBep9ttTTdYmU15QNA0XVolrmfrG05GBrCMKR+jEI+lM58j1fi1Rn3g7mOYkEs+ 62 | # BagvsBizWaSvQVOOCAUQLSrJOgZMHC6pMVFWZKyazKyXmCmKl5CH6p22MIIEujCC 63 | # A6KgAwIBAgIKYQKSSgAAAAAAIDANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJV 64 | # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE 65 | # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSEwHwYDVQQDExhNaWNyb3NvZnQgVGlt 66 | # ZS1TdGFtcCBQQ0EwHhcNMTIwMTA5MjIyNTU5WhcNMTMwNDA5MjIyNTU5WjCBszEL 67 | # MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v 68 | # bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9Q 69 | # UjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOkI4RUMtMzBBNC03MTQ0MSUwIwYD 70 | # VQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjANBgkqhkiG9w0B 71 | # AQEFAAOCAQ8AMIIBCgKCAQEAzWPD96K1R9n5OZRTrGuPpnk4IfTRbj0VOBbBcyyZ 72 | # j/vgPFvhokyLsquLtPJKx7mTUNEm9YdTsHp180cPFytnLGTrYOdKjOCLXsRWaTc6 73 | # KgRdFwHIv6m308mro5GogeM/LbfY5MR4AHk5z/3HZOIjEnieDHYnSY+arA504wZV 74 | # VUnI7aF8cEVhfrJxFh7hwUG50tIy6VIk8zZQBNfdbzxJ1QvUdkD8ZWUTfpVROtX/ 75 | # uJqnV2tLFeU3WB/cAA3FrurfgUf58FKu5s9arOAUSqZxlID6/bAjMGDpg2CsDiQe 76 | # /xHy56VVYpXun3+eKdbNSwp2g/BDBN8GSSDyU1pEsFF6OQIDAQABo4IBCTCCAQUw 77 | # HQYDVR0OBBYEFM0ZrGFNlGcr9q+UdVnb8FgAg6E6MB8GA1UdIwQYMBaAFCM0+NlS 78 | # RnAK7UD7dvuzK7DDNbMPMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly9jcmwubWlj 79 | # cm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY3Jvc29mdFRpbWVTdGFtcFBD 80 | # QS5jcmwwWAYIKwYBBQUHAQEETDBKMEgGCCsGAQUFBzAChjxodHRwOi8vd3d3Lm1p 81 | # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY3Jvc29mdFRpbWVTdGFtcFBDQS5jcnQw 82 | # EwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZIhvcNAQEFBQADggEBAFEc1t82HdyA 83 | # vAKnxpnfFsiQBmkVmjK582QQ0orzYikbeY/KYKmzXcTkFi01jESb8fRcYaRBrpqL 84 | # ulDRanlqs2KMnU1RUAupjtS/ohDAR9VOdVKJHj+Wao8uQBQGcu4/cFmSXYXtg5n6 85 | # goSe5AMBIROrJ9bMcUnl2h3/bzwJTtWNZugMyX/uMRQCN197aeyJPkV/JUTnHxrW 86 | # xRrDSuTh8YSY50/5qZinGEbshGzsqQMK/Xx6Uh2ca6SoD5iSpJJ4XCt4432yx9m2 87 | # cH3fW3NTv6rUZlBL8Mk7lYXlwUplnSVYULsgVJF5OhsHXGpXKK8xx5/nwx3uR/0n 88 | # 13/PdNxlxT8wggW8MIIDpKADAgECAgphMyYaAAAAAAAxMA0GCSqGSIb3DQEBBQUA 89 | # MF8xEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJkiaJk/IsZAEZFgltaWNyb3Nv 90 | # ZnQxLTArBgNVBAMTJE1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 91 | # eTAeFw0xMDA4MzEyMjE5MzJaFw0yMDA4MzEyMjI5MzJaMHkxCzAJBgNVBAYTAlVT 92 | # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK 93 | # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xIzAhBgNVBAMTGk1pY3Jvc29mdCBDb2Rl 94 | # IFNpZ25pbmcgUENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsnJZ 95 | # XBkwZL8dmmAgIEKZdlNsPhvWb8zL8epr/pcWEODfOnSDGrcvoDLs/97CQk4j1XIA 96 | # 2zVXConKriBJ9PBorE1LjaW9eUtxm0cH2v0l3511iM+qc0R/14Hb873yNqTJXEXc 97 | # r6094CholxqnpXJzVvEXlOT9NZRyoNZ2Xx53RYOFOBbQc1sFumdSjaWyaS/aGQv+ 98 | # knQp4nYvVN0UMFn40o1i/cvJX0YxULknE+RAMM9yKRAoIsc3Tj2gMj2QzaE4BoVc 99 | # TlaCKCoFMrdL109j59ItYvFFPeesCAD2RqGe0VuMJlPoeqpK8kbPNzw4nrR3XKUX 100 | # no3LEY9WPMGsCV8D0wIDAQABo4IBXjCCAVowDwYDVR0TAQH/BAUwAwEB/zAdBgNV 101 | # HQ4EFgQUyxHoytK0FlgByTcuMxYWuUyaCh8wCwYDVR0PBAQDAgGGMBIGCSsGAQQB 102 | # gjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFP3RMU7TJoqV4ZhgO6gxb6Y8vNgt 103 | # MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMB8GA1UdIwQYMBaAFA6sgmBAVieX 104 | # 5SUT/CrhClOVWeSkMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwubWljcm9z 105 | # b2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL21pY3Jvc29mdHJvb3RjZXJ0LmNybDBU 106 | # BggrBgEFBQcBAQRIMEYwRAYIKwYBBQUHMAKGOGh0dHA6Ly93d3cubWljcm9zb2Z0 107 | # LmNvbS9wa2kvY2VydHMvTWljcm9zb2Z0Um9vdENlcnQuY3J0MA0GCSqGSIb3DQEB 108 | # BQUAA4ICAQBZOT5/Jkav629AsTK1ausOL26oSffrX3XtTDst10OtC/7L6S0xoyPM 109 | # fFCYgCFdrD0vTLqiqFac43C7uLT4ebVJcvc+6kF/yuEMF2nLpZwgLfoLUMRWzS3j 110 | # StK8cOeoDaIDpVbguIpLV/KVQpzx8+/u44YfNDy4VprwUyOFKqSCHJPilAcd8uJO 111 | # +IyhyugTpZFOyBvSj3KVKnFtmxr4HPBT1mfMIv9cHc2ijL0nsnljVkSiUc356aNY 112 | # Vt2bAkVEL1/02q7UgjJu/KSVE+Traeepoiy+yCsQDmWOmdv1ovoSJgllOJTxeh9K 113 | # u9HhVujQeJYYXMk1Fl/dkx1Jji2+rTREHO4QFRoAXd01WyHOmMcJ7oUOjE9tDhNO 114 | # PXwpSJxy0fNsysHscKNXkld9lI2gG0gDWvfPo2cKdKU27S0vF8jmcjcS9G+xPGeC 115 | # +VKyjTMWZR4Oit0Q3mT0b85G1NMX6XnEBLTT+yzfH4qerAr7EydAreT54al/RrsH 116 | # YEdlYEBOsELsTu2zdnnYCjQJbRyAMR/iDlTd5aH75UcQrWSY/1AWLny/BSF64pVB 117 | # J2nDk4+VyY3YmyGuDVyc8KKuhmiDDGotu3ZrAB2WrfIWe/YWgyS5iM9qqEcxL5rc 118 | # 43E91wB+YkfRzojJuBj6DnKNwaM9rwJAav9pm5biEKgQtDdQCNbDPTCCBgcwggPv 119 | # oAMCAQICCmEWaDQAAAAAABwwDQYJKoZIhvcNAQEFBQAwXzETMBEGCgmSJomT8ixk 120 | # ARkWA2NvbTEZMBcGCgmSJomT8ixkARkWCW1pY3Jvc29mdDEtMCsGA1UEAxMkTWlj 121 | # cm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA3MDQwMzEyNTMw 122 | # OVoXDTIxMDQwMzEzMDMwOVowdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp 123 | # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw 124 | # b3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBMIIBIjAN 125 | # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn6Fssd/bSJIqfGsuGeG94uPFmVEj 126 | # UK3O3RhOJA/u0afRTK10MCAR6wfVVJUVSZQbQpKumFwwJtoAa+h7veyJBw/3DgSY 127 | # 8InMH8szJIed8vRnHCz8e+eIHernTqOhwSNTyo36Rc8J0F6v0LBCBKL5pmyTZ9co 128 | # 3EZTsIbQ5ShGLieshk9VUgzkAyz7apCQMG6H81kwnfp+1pez6CGXfvjSE/MIt1Nt 129 | # UrRFkJ9IAEpHZhEnKWaol+TTBoFKovmEpxFHFAmCn4TtVXj+AZodUAiFABAwRu23 130 | # 3iNGu8QtVJ+vHnhBMXfMm987g5OhYQK1HQ2x/PebsgHOIktU//kFw8IgCwIDAQAB 131 | # o4IBqzCCAacwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUIzT42VJGcArtQPt2 132 | # +7MrsMM1sw8wCwYDVR0PBAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMIGYBgNVHSME 133 | # gZAwgY2AFA6sgmBAVieX5SUT/CrhClOVWeSkoWOkYTBfMRMwEQYKCZImiZPyLGQB 134 | # GRYDY29tMRkwFwYKCZImiZPyLGQBGRYJbWljcm9zb2Z0MS0wKwYDVQQDEyRNaWNy 135 | # b3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCEHmtFqFKoKWtTHNY9AcT 136 | # LmUwUAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC5taWNyb3NvZnQuY29tL3Br 137 | # aS9jcmwvcHJvZHVjdHMvbWljcm9zb2Z0cm9vdGNlcnQuY3JsMFQGCCsGAQUFBwEB 138 | # BEgwRjBEBggrBgEFBQcwAoY4aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9j 139 | # ZXJ0cy9NaWNyb3NvZnRSb290Q2VydC5jcnQwEwYDVR0lBAwwCgYIKwYBBQUHAwgw 140 | # DQYJKoZIhvcNAQEFBQADggIBABCXisNcA0Q23em0rXfbznlRTQGxLnRxW20ME6vO 141 | # vnuPuC7UEqKMbWK4VwLLTiATUJndekDiV7uvWJoc4R0Bhqy7ePKL0Ow7Ae7ivo8K 142 | # BciNSOLwUxXdT6uS5OeNatWAweaU8gYvhQPpkSokInD79vzkeJkuDfcH4nC8GE6d 143 | # jmsKcpW4oTmcZy3FUQ7qYlw/FpiLID/iBxoy+cwxSnYxPStyC8jqcD3/hQoT38IK 144 | # YY7w17gX606Lf8U1K16jv+u8fQtCe9RTciHuMMq7eGVcWwEXChQO0toUmPU8uWZY 145 | # sy0v5/mFhsxRVuidcJRsrDlM1PZ5v6oYemIp76KbKTQGdxpiyT0ebR+C8AvHLLvP 146 | # Q7Pl+ex9teOkqHQ1uE7FcSMSJnYLPFKMcVpGQxS8s7OwTWfIn0L/gHkhgJ4VMGbo 147 | # QhJeGsieIiHQQ+kr6bv0SMws1NgygEwmKkgkX1rqVu+m3pmdyjpvvYEndAYR7nYh 148 | # v5uCwSdUtrFqPYmhdmG0bqETpr+qR/ASb/2KMmyy/t9RyIwjyWa9nR2HEmQCPS2v 149 | # WY+45CHltbDKY7R4VAXUQS5QrJSwpXirs6CWdRrZkocTdSIvMqgIbqBbjCW/oO+E 150 | # yiHW6x5PyZruSeD3AWVviQt9yGnI5m7qp5fOMSn/DsVbXNhNG6HY+i+ePy5VFmvJ 151 | # E6P9MYIEhTCCBIECAQEwgYcweTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp 152 | # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw 153 | # b3JhdGlvbjEjMCEGA1UEAxMaTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0ECCmEZ 154 | # zJMAAQAAAGYwCQYFKw4DAhoFAKCBsDAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB 155 | # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU 156 | # WQ2AdtM5zwQcEcFbsSevYrmN6UQwUAYKKwYBBAGCNwIBDDFCMECgIoAgAEUAbgB0 157 | # AGkAdAB5ACAARgByAGEAbQBlAHcAbwByAGuhGoAYaHR0cDovL21zZG4uY29tL2Rh 158 | # dGEvZWYgMA0GCSqGSIb3DQEBAQUABIIBAAp6IKF/Uj/9lpK3SAcA7JJxjVoqi+yI 159 | # n0i9qNP5b4+zTSrtpnPDibOaQvhdUlEsAlEjnJTRCwYR9zobPyxJfGoh9j/qkgcU 160 | # wWBIdmNhzMEzVDJwlE9puRipHQNP6ftcbaz9SOD40aOQ8skR9ecYuHW9SGG0levm 161 | # m2Q/UWxmxVvtv6HnYzWUn6vHrJmiRk+t1ckG9Dxq2GPnBA+hGrRdYaijPBSwSWcg 162 | # FnBsl4s88UVL7N8hpKYOQGnqGda6V1LJIgNPKoGNoPllFeJWXKgClvJ6majpd6dz 163 | # o8S6A9a19D2Dh1l0cbwpI2ZFZjfY9UOVSH33i6fk7CM0aCVe9z3dcB+hggIfMIIC 164 | # GwYJKoZIhvcNAQkGMYICDDCCAggCAQEwgYUwdzELMAkGA1UEBhMCVVMxEzARBgNV 165 | # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv 166 | # c29mdCBDb3Jwb3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0IFRpbWUtU3RhbXAg 167 | # UENBAgphApJKAAAAAAAgMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZI 168 | # hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xMjA2MjgyMDQzMzlaMCMGCSqGSIb3DQEJ 169 | # BDEWBBTcH0Qic4YQ6MzFbjR1RWKCxjK8pzANBgkqhkiG9w0BAQUFAASCAQAdMhoS 170 | # z2zXLJyB1RIjdnGlDxLKzXF+rxImjMI7VfId2vIg4FaGIPqnN0BBTp8o+HZCv3cM 171 | # ZV/okS8w9k/82jWjJ183l9fn3moQe4qbVlV6yUJvPFpW47LFrEAXgdmL8bgA/VOW 172 | # HtJRP52lPDsb7J1WjqNOh7KkyD5x0Y8Pwrb+Xc63ibtTjOeAttPxKk+1gZh95wUA 173 | # ykjw7RKZLHfyJ9Ph5lCkzDQrXXwGGPuzaZVO+pkowgy2yCPRecShGBCKbCyOZlhT 174 | # BS1WVJDHS95N732o0lPzWE5rTQe/awv8xkgCe9e8ci4S7/lSnj3aVOLbM3S8jG4x 175 | # Oi4rxrjYTjts1n2P 176 | # SIG # End signature block 177 | -------------------------------------------------------------------------------- /packages/EntityFramework.5.0.0/tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | function Invoke-ConnectionFactoryConfigurator($assemblyPath, $project) 4 | { 5 | $appDomain = [AppDomain]::CreateDomain( 6 | 'EntityFramework.PowerShell', 7 | $null, 8 | (New-Object System.AppDomainSetup -Property @{ ShadowCopyFiles = 'true' })) 9 | 10 | $appDomain.CreateInstanceFrom( 11 | $assemblyPath, 12 | 'System.Data.Entity.ConnectionFactoryConfig.ConnectionFactoryConfigurator', 13 | $false, 14 | 0, 15 | $null, 16 | $project, 17 | $null, 18 | $null) | Out-Null 19 | 20 | [AppDomain]::Unload($appDomain) 21 | } 22 | 23 | Invoke-ConnectionFactoryConfigurator (Join-Path $toolsPath EntityFramework.PowerShell.dll) $project 24 | 25 | Write-Host 26 | Write-Host "Type 'get-help EntityFramework' to see all available Entity Framework commands." 27 | 28 | # SIG # Begin signature block 29 | # MIIaRgYJKoZIhvcNAQcCoIIaNzCCGjMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB 30 | # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR 31 | # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU4nG54zEClXzFX9aYwYpo8BH3 32 | # YWygghUtMIIEoDCCA4igAwIBAgIKYRnMkwABAAAAZjANBgkqhkiG9w0BAQUFADB5 33 | # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk 34 | # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSMwIQYDVQQDExpN 35 | # aWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQTAeFw0xMTEwMTAyMDMyMjVaFw0xMzAx 36 | # MTAyMDMyMjVaMIGDMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ 37 | # MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u 38 | # MQ0wCwYDVQQLEwRNT1BSMR4wHAYDVQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24w 39 | # ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDuW759ESTjhgbgZv9ItRe9 40 | # AuS0DDLwcj59LofXTqGxp0Mv92WeMeEyMUWu18EkhCHXLrWEfvo101Mc17ZRHk/O 41 | # ZrnrtwwC/SlcraiH9soitNW/CHX1inCPY9fvih7pj0MkZFrTh32QbTusds1XNn3o 42 | # vBBWrJjwiV0uZMavJgleHmMV8T2/Fo+ZiALDMLfBC2AfD3LM1reoNRKGm6ELCuaT 43 | # W476VJzB8xlfQo0Snx0/kLcnE4MZMoId89mH1CGyPKK2B0/XJKrujfWz2fr5OU+n 44 | # 6fKvWVL03EGbLxFwY93q3qrxbSEEEFMzu7JPxeFTskFlR2439rzpmxZBkWsuWzDD 45 | # AgMBAAGjggEdMIIBGTATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUG1IO 46 | # 8xEqt8CJwxGBPdSWWLmjU24wDgYDVR0PAQH/BAQDAgeAMB8GA1UdIwQYMBaAFMsR 47 | # 6MrStBZYAck3LjMWFrlMmgofMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwu 48 | # bWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY0NvZFNpZ1BDQV8wOC0z 49 | # MS0yMDEwLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93 50 | # d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljQ29kU2lnUENBXzA4LTMxLTIw 51 | # MTAuY3J0MA0GCSqGSIb3DQEBBQUAA4IBAQClWzZsrU6baRLjb4oCm2l3w2xkciiI 52 | # 2T1FbSwYe9QoLxPiWWobwgs0t4r96rmU7Acx5mr0dQTTp9peOgaeEP2pDb2cUUNv 53 | # /2eUnOHPfPAksDXMg13u2sBvNknAWgpX9nPhnvPjCEw7Pi/M0s3uTyJw9wQfAqZL 54 | # m7iPXIgONpRsMwe4qa1RoNDC3I4iEr3D34LXVqH33fClIFcQEJ3urIZ0bHGbwfDy 55 | # wnBep9ttTTdYmU15QNA0XVolrmfrG05GBrCMKR+jEI+lM58j1fi1Rn3g7mOYkEs+ 56 | # BagvsBizWaSvQVOOCAUQLSrJOgZMHC6pMVFWZKyazKyXmCmKl5CH6p22MIIEujCC 57 | # A6KgAwIBAgIKYQUZlgAAAAAAGzANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJV 58 | # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE 59 | # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSEwHwYDVQQDExhNaWNyb3NvZnQgVGlt 60 | # ZS1TdGFtcCBQQ0EwHhcNMTEwNzI1MjA0MjE5WhcNMTIxMDI1MjA0MjE5WjCBszEL 61 | # MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v 62 | # bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9Q 63 | # UjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjlFNzgtODY0Qi0wMzlEMSUwIwYD 64 | # VQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjANBgkqhkiG9w0B 65 | # AQEFAAOCAQ8AMIIBCgKCAQEA08s7U6KfRKN6q01WcVOKd6o3k34BPv2rAqNTqf/R 66 | # sSLFAJDndW7uGOiBDhPF2GEAvh+gdjsEDQTFBKCo/ENTBqEEBLkLkpgCYjjv1DMS 67 | # 9ys9e++tRVeFlSCf12M0nGJGjr6u4NmeOfapVf3P53fmNRPvXOi/SJNPGkMHWDiK 68 | # f4UUbOrJ0Et6gm7L0xVgCBSJlKhbPzrJPyB9bS9YGn3Kiji8w8I5aNgtWBoj7SoQ 69 | # CFogjIKl7dGXRZKFzMM3g98NmHzF07bgmVPYeAj15SMhB2KGWmppGf1w+VM0gfcl 70 | # MRmGh4vAVZr9qkw1Ff1b6ZXJq1OYKV8speElD2TF8rAndQIDAQABo4IBCTCCAQUw 71 | # HQYDVR0OBBYEFHkj56ENvlUsaBgpYoJn1vPhNjhaMB8GA1UdIwQYMBaAFCM0+NlS 72 | # RnAK7UD7dvuzK7DDNbMPMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly9jcmwubWlj 73 | # cm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY3Jvc29mdFRpbWVTdGFtcFBD 74 | # QS5jcmwwWAYIKwYBBQUHAQEETDBKMEgGCCsGAQUFBzAChjxodHRwOi8vd3d3Lm1p 75 | # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY3Jvc29mdFRpbWVTdGFtcFBDQS5jcnQw 76 | # EwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZIhvcNAQEFBQADggEBAEfCdoFbMd1v 77 | # 0zyZ8npsfpcTUCwFFxsQuEShtYz0Vs+9sCG0ZG1hHNju6Ov1ku5DohhEw/r67622 78 | # XH+XbUu1Q/snYXgIVHyx+a+YCrR0xKroLVDEff59TqGZ1icot67Y37GPgyKOzvN5 79 | # /GEUbb/rzISw36O7WwW36lT1Yh1sJ6ZjS/rjofq734WWZWlTsLZxmGQmZr3F8Vxi 80 | # vJH0PZxLQgANzzgFFCZa3CoFS39qmTjY3XOZos6MUCSepOv1P4p4zFSZXSVmpEEG 81 | # KK9JxLRSlOzeAoNk/k3U/0ui/CmA2+4/qzztM4jKvyJg0Fw7BLAKtJhtPKc6T5rR 82 | # ARYRYopBdqAwggW8MIIDpKADAgECAgphMyYaAAAAAAAxMA0GCSqGSIb3DQEBBQUA 83 | # MF8xEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJkiaJk/IsZAEZFgltaWNyb3Nv 84 | # ZnQxLTArBgNVBAMTJE1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 85 | # eTAeFw0xMDA4MzEyMjE5MzJaFw0yMDA4MzEyMjI5MzJaMHkxCzAJBgNVBAYTAlVT 86 | # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK 87 | # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xIzAhBgNVBAMTGk1pY3Jvc29mdCBDb2Rl 88 | # IFNpZ25pbmcgUENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsnJZ 89 | # XBkwZL8dmmAgIEKZdlNsPhvWb8zL8epr/pcWEODfOnSDGrcvoDLs/97CQk4j1XIA 90 | # 2zVXConKriBJ9PBorE1LjaW9eUtxm0cH2v0l3511iM+qc0R/14Hb873yNqTJXEXc 91 | # r6094CholxqnpXJzVvEXlOT9NZRyoNZ2Xx53RYOFOBbQc1sFumdSjaWyaS/aGQv+ 92 | # knQp4nYvVN0UMFn40o1i/cvJX0YxULknE+RAMM9yKRAoIsc3Tj2gMj2QzaE4BoVc 93 | # TlaCKCoFMrdL109j59ItYvFFPeesCAD2RqGe0VuMJlPoeqpK8kbPNzw4nrR3XKUX 94 | # no3LEY9WPMGsCV8D0wIDAQABo4IBXjCCAVowDwYDVR0TAQH/BAUwAwEB/zAdBgNV 95 | # HQ4EFgQUyxHoytK0FlgByTcuMxYWuUyaCh8wCwYDVR0PBAQDAgGGMBIGCSsGAQQB 96 | # gjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFP3RMU7TJoqV4ZhgO6gxb6Y8vNgt 97 | # MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMB8GA1UdIwQYMBaAFA6sgmBAVieX 98 | # 5SUT/CrhClOVWeSkMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwubWljcm9z 99 | # b2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL21pY3Jvc29mdHJvb3RjZXJ0LmNybDBU 100 | # BggrBgEFBQcBAQRIMEYwRAYIKwYBBQUHMAKGOGh0dHA6Ly93d3cubWljcm9zb2Z0 101 | # LmNvbS9wa2kvY2VydHMvTWljcm9zb2Z0Um9vdENlcnQuY3J0MA0GCSqGSIb3DQEB 102 | # BQUAA4ICAQBZOT5/Jkav629AsTK1ausOL26oSffrX3XtTDst10OtC/7L6S0xoyPM 103 | # fFCYgCFdrD0vTLqiqFac43C7uLT4ebVJcvc+6kF/yuEMF2nLpZwgLfoLUMRWzS3j 104 | # StK8cOeoDaIDpVbguIpLV/KVQpzx8+/u44YfNDy4VprwUyOFKqSCHJPilAcd8uJO 105 | # +IyhyugTpZFOyBvSj3KVKnFtmxr4HPBT1mfMIv9cHc2ijL0nsnljVkSiUc356aNY 106 | # Vt2bAkVEL1/02q7UgjJu/KSVE+Traeepoiy+yCsQDmWOmdv1ovoSJgllOJTxeh9K 107 | # u9HhVujQeJYYXMk1Fl/dkx1Jji2+rTREHO4QFRoAXd01WyHOmMcJ7oUOjE9tDhNO 108 | # PXwpSJxy0fNsysHscKNXkld9lI2gG0gDWvfPo2cKdKU27S0vF8jmcjcS9G+xPGeC 109 | # +VKyjTMWZR4Oit0Q3mT0b85G1NMX6XnEBLTT+yzfH4qerAr7EydAreT54al/RrsH 110 | # YEdlYEBOsELsTu2zdnnYCjQJbRyAMR/iDlTd5aH75UcQrWSY/1AWLny/BSF64pVB 111 | # J2nDk4+VyY3YmyGuDVyc8KKuhmiDDGotu3ZrAB2WrfIWe/YWgyS5iM9qqEcxL5rc 112 | # 43E91wB+YkfRzojJuBj6DnKNwaM9rwJAav9pm5biEKgQtDdQCNbDPTCCBgcwggPv 113 | # oAMCAQICCmEWaDQAAAAAABwwDQYJKoZIhvcNAQEFBQAwXzETMBEGCgmSJomT8ixk 114 | # ARkWA2NvbTEZMBcGCgmSJomT8ixkARkWCW1pY3Jvc29mdDEtMCsGA1UEAxMkTWlj 115 | # cm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA3MDQwMzEyNTMw 116 | # OVoXDTIxMDQwMzEzMDMwOVowdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp 117 | # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw 118 | # b3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBMIIBIjAN 119 | # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn6Fssd/bSJIqfGsuGeG94uPFmVEj 120 | # UK3O3RhOJA/u0afRTK10MCAR6wfVVJUVSZQbQpKumFwwJtoAa+h7veyJBw/3DgSY 121 | # 8InMH8szJIed8vRnHCz8e+eIHernTqOhwSNTyo36Rc8J0F6v0LBCBKL5pmyTZ9co 122 | # 3EZTsIbQ5ShGLieshk9VUgzkAyz7apCQMG6H81kwnfp+1pez6CGXfvjSE/MIt1Nt 123 | # UrRFkJ9IAEpHZhEnKWaol+TTBoFKovmEpxFHFAmCn4TtVXj+AZodUAiFABAwRu23 124 | # 3iNGu8QtVJ+vHnhBMXfMm987g5OhYQK1HQ2x/PebsgHOIktU//kFw8IgCwIDAQAB 125 | # o4IBqzCCAacwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUIzT42VJGcArtQPt2 126 | # +7MrsMM1sw8wCwYDVR0PBAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMIGYBgNVHSME 127 | # gZAwgY2AFA6sgmBAVieX5SUT/CrhClOVWeSkoWOkYTBfMRMwEQYKCZImiZPyLGQB 128 | # GRYDY29tMRkwFwYKCZImiZPyLGQBGRYJbWljcm9zb2Z0MS0wKwYDVQQDEyRNaWNy 129 | # b3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCEHmtFqFKoKWtTHNY9AcT 130 | # LmUwUAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC5taWNyb3NvZnQuY29tL3Br 131 | # aS9jcmwvcHJvZHVjdHMvbWljcm9zb2Z0cm9vdGNlcnQuY3JsMFQGCCsGAQUFBwEB 132 | # BEgwRjBEBggrBgEFBQcwAoY4aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9j 133 | # ZXJ0cy9NaWNyb3NvZnRSb290Q2VydC5jcnQwEwYDVR0lBAwwCgYIKwYBBQUHAwgw 134 | # DQYJKoZIhvcNAQEFBQADggIBABCXisNcA0Q23em0rXfbznlRTQGxLnRxW20ME6vO 135 | # vnuPuC7UEqKMbWK4VwLLTiATUJndekDiV7uvWJoc4R0Bhqy7ePKL0Ow7Ae7ivo8K 136 | # BciNSOLwUxXdT6uS5OeNatWAweaU8gYvhQPpkSokInD79vzkeJkuDfcH4nC8GE6d 137 | # jmsKcpW4oTmcZy3FUQ7qYlw/FpiLID/iBxoy+cwxSnYxPStyC8jqcD3/hQoT38IK 138 | # YY7w17gX606Lf8U1K16jv+u8fQtCe9RTciHuMMq7eGVcWwEXChQO0toUmPU8uWZY 139 | # sy0v5/mFhsxRVuidcJRsrDlM1PZ5v6oYemIp76KbKTQGdxpiyT0ebR+C8AvHLLvP 140 | # Q7Pl+ex9teOkqHQ1uE7FcSMSJnYLPFKMcVpGQxS8s7OwTWfIn0L/gHkhgJ4VMGbo 141 | # QhJeGsieIiHQQ+kr6bv0SMws1NgygEwmKkgkX1rqVu+m3pmdyjpvvYEndAYR7nYh 142 | # v5uCwSdUtrFqPYmhdmG0bqETpr+qR/ASb/2KMmyy/t9RyIwjyWa9nR2HEmQCPS2v 143 | # WY+45CHltbDKY7R4VAXUQS5QrJSwpXirs6CWdRrZkocTdSIvMqgIbqBbjCW/oO+E 144 | # yiHW6x5PyZruSeD3AWVviQt9yGnI5m7qp5fOMSn/DsVbXNhNG6HY+i+ePy5VFmvJ 145 | # E6P9MYIEgzCCBH8CAQEwgYcweTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp 146 | # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw 147 | # b3JhdGlvbjEjMCEGA1UEAxMaTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0ECCmEZ 148 | # zJMAAQAAAGYwCQYFKw4DAhoFAKCBsDAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB 149 | # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU 150 | # aRQ2a/UgAzqOb3Wvyd0Y2tRWtIEwUAYKKwYBBAGCNwIBDDFCMECgIoAgAEUAbgB0 151 | # AGkAdAB5ACAARgByAGEAbQBlAHcAbwByAGuhGoAYaHR0cDovL21zZG4uY29tL2Rh 152 | # dGEvZWYgMA0GCSqGSIb3DQEBAQUABIIBAMQdz1xbjYGj57Z6LNm3laDw2S6QJFye 153 | # QUSbvlY7kcxqlHQrERkp3wwR34emJSnTayLTcTPaCCvzUaGsZi86i+IW6HdA/3A/ 154 | # IwEZgAkai/qXZCYEEBvV9ja+iMRowFPAySU+ROh4LFbCTLzm4vez6qaLyui/JQNr 155 | # 46DZptV5XM0idAbgOfmtCMMipqRkrNqt7Zj8cuxu3cJBKOvhUOdLfEIxq1UW9pNy 156 | # 8c/aOStE0kLFInw3G1GL9IJnS43eTcgeIDMkrwX70o+rLS7lN1U3txL25IrBTUcY 157 | # Q6dxj4zSDxIjn3Tq2jqa8B6lR1OMEahj4INmR6vC+mFNspHODHWgt7GhggIdMIIC 158 | # GQYJKoZIhvcNAQkGMYICCjCCAgYCAQEwgYUwdzELMAkGA1UEBhMCVVMxEzARBgNV 159 | # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv 160 | # c29mdCBDb3Jwb3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0IFRpbWUtU3RhbXAg 161 | # UENBAgphBRmWAAAAAAAbMAcGBSsOAwIaoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3 162 | # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTIwNjI4MjA0MzU0WjAjBgkqhkiG9w0BCQQx 163 | # FgQUlE+8FmmwI9Hd6gz+luAdOPsKxHgwDQYJKoZIhvcNAQEFBQAEggEAiJCupwRm 164 | # YW3NHK2EdgaQ+VCIjXwVrEj6ElX4c30nAYXxnCOIesErL/N/jMYnM3Fo+GNsOikL 165 | # x9Mzo4sZv/c6bchLtnagS6MzQyDFiBPF+pngSMg2PpIDHsIBg2vPzClWx6+hCDxE 166 | # Yf9f7/s/vQEpEbHLjzQZJqoji2LV5HRxnHbT3J13atUF2yqgzyTRlOF2MPp3vLX1 167 | # 7q5KnOBrWsfyxoYskJEddsbH7zilomWyVZ2zcpG8Ui/h2xoN50AXtMQntx9VYxwT 168 | # D5U5ECSdKzXeUIwktYBPtxor5yGBda63PNxjUHYXSRvFrdnLtXTiMiIQzEzJUdk9 169 | # 6p75IHbjyjvZfg== 170 | # SIG # End signature block 171 | -------------------------------------------------------------------------------- /packages/EntityFramework.6.1.3/EntityFramework.6.1.3.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuheylZ/GenericDataManager/6fa8bd6da2dd7187dfde213f86bbcd4aba8d97a2/packages/EntityFramework.6.1.3/EntityFramework.6.1.3.nupkg --------------------------------------------------------------------------------