PageRenderTime 127ms CodeModel.GetById 30ms app.highlight 77ms RepoModel.GetById 14ms app.codeStats 0ms

/Tools/LinqPad/LINQPad/Extensibility/DataContext/EntityFrameworkDbContextDriver.cs

https://github.com/vishalsh-spec/TestProject
C# | 459 lines | 423 code | 36 blank | 0 comment | 66 complexity | a0acbbf033b39eb1bd02135ad4ffd1b5 MD5 | raw file
  1namespace LINQPad.Extensibility.DataContext
  2{
  3    using LINQPad;
  4    using LINQPad.ExecutionModel;
  5    using LINQPad.Extensibility.Internal;
  6    using LINQPad.UI;
  7    using System;
  8    using System.Collections.Generic;
  9    using System.Data;
 10    using System.Data.Common;
 11    using System.Data.EntityClient;
 12    using System.Data.Objects;
 13    using System.IO;
 14    using System.Linq;
 15    using System.Reflection;
 16    using System.Reflection.Emit;
 17    using System.Security.Cryptography;
 18    using System.Text;
 19    using System.Windows.Forms;
 20    using System.Xml.Linq;
 21
 22    internal class EntityFrameworkDbContextDriver : StaticDataContextDriver
 23    {
 24        private static bool _cxFactoryPatched;
 25        private static Assembly _efAssembly;
 26        private static string _efDllPath;
 27        private static bool _efResolverInstalled;
 28        private static string _lastEfPath;
 29        private static string _lastEfPathGac;
 30        private static string _lastEfPathInput;
 31
 32        public override bool AreRepositoriesEquivalent(IConnectionInfo c1, IConnectionInfo c2)
 33        {
 34            return ((c1.CustomTypeInfo.IsEquivalent(c2.CustomTypeInfo) && string.Equals(c1.AppConfigPath, c2.AppConfigPath, StringComparison.InvariantCultureIgnoreCase)) && string.Equals(c1.DatabaseInfo.CustomCxString, c2.DatabaseInfo.CustomCxString, StringComparison.InvariantCultureIgnoreCase));
 35        }
 36
 37        private static void CheckEFAssemblyResolver(IConnectionInfo cxInfo)
 38        {
 39            try
 40            {
 41                string path = Path.Combine(Path.GetDirectoryName(cxInfo.CustomTypeInfo.CustomAssemblyPath), "EntityFramework.dll");
 42                if (File.Exists(path))
 43                {
 44                    _efDllPath = path;
 45                    InstallEFResolver();
 46                }
 47            }
 48            catch
 49            {
 50            }
 51        }
 52
 53        private static void CheckForUnpatchedCx(object dbContext)
 54        {
 55            if (!(GetIDbConnection(dbContext) is LINQPadDbConnection))
 56            {
 57                LINQPadDbController.UnpatchProviderConfigTable();
 58            }
 59        }
 60
 61        public override void ExecuteESqlQuery(IConnectionInfo cxInfo, string query)
 62        {
 63            EntityConnection connection;
 64            object dbContext = base.InstantiateBaseContext(cxInfo);
 65            CheckForUnpatchedCx(dbContext);
 66            string eSqlCxString = GetESqlCxString(dbContext);
 67            EntityConnectionStringBuilder builder = new EntityConnectionStringBuilder(eSqlCxString);
 68            string str2 = builder["metadata"] as string;
 69            if ((str2 != null) && str2.Trim().ToUpperInvariant().StartsWith("READER:"))
 70            {
 71                connection = new EntityConnection(GetObjectContext(dbContext).MetadataWorkspace, (DbConnection) GetIDbConnection(dbContext));
 72            }
 73            else
 74            {
 75                connection = new EntityConnection(eSqlCxString);
 76            }
 77            using (connection)
 78            {
 79                EntityCommand command = new EntityCommand(query, connection);
 80                connection.Open();
 81                command.ExecuteReader(CommandBehavior.SequentialAccess).Dump<EntityDataReader>();
 82            }
 83        }
 84
 85        public override string GetAppConfigPath(IConnectionInfo cxInfo)
 86        {
 87            Func<XElement, bool> predicate = null;
 88            if (!((!string.IsNullOrWhiteSpace(cxInfo.AppConfigPath) && !string.IsNullOrWhiteSpace(cxInfo.CustomTypeInfo.CustomTypeName)) && File.Exists(cxInfo.AppConfigPath)))
 89            {
 90                return base.GetAppConfigPath(cxInfo);
 91            }
 92            string typeName = cxInfo.CustomTypeInfo.CustomTypeName.Split(new char[] { '.' }).Last<string>();
 93            XElement element = null;
 94            try
 95            {
 96                element = XElement.Load(cxInfo.AppConfigPath);
 97                IEnumerable<XElement> source = from x in element.Elements("connectionStrings") select x.Elements("add");
 98                if (source.Any<XElement>(cx => ((string) cx.Attribute("name")) == "UserQuery"))
 99                {
100                    return base.GetAppConfigPath(cxInfo);
101                }
102                if (predicate == null)
103                {
104                    predicate = x => ((string) x.Attribute("name")) == typeName;
105                }
106                XElement content = source.FirstOrDefault<XElement>(predicate);
107                if (content == null)
108                {
109                    return base.GetAppConfigPath(cxInfo);
110                }
111                content.AddAfterSelf(content);
112                ((XElement) content.NextNode).Attribute("name").SetValue("UserQuery");
113            }
114            catch
115            {
116                return base.GetAppConfigPath(cxInfo);
117            }
118            string str2 = string.Concat((IEnumerable<string>) (from b in SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(cxInfo.AppConfigPath)).Take<byte>(8) select b.ToString("X2"))) + ".config";
119            string fileName = Path.Combine(Program.TempFolder, str2);
120            element.Save(fileName);
121            return fileName;
122        }
123
124        public override IEnumerable<string> GetAssembliesToAdd(IConnectionInfo cxInfo)
125        {
126            string efPath = GetEfPath(cxInfo, false);
127            if (efPath != null)
128            {
129                return new string[] { efPath };
130            }
131            return new string[] { "EntityFramework, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" };
132        }
133
134        public override string GetConnectionDescription(IConnectionInfo cxInfo)
135        {
136            return (cxInfo.CustomTypeInfo.CustomTypeName.Split(new char[] { '.' }).Last<string>() + " in " + cxInfo.CustomTypeInfo.CustomAssemblyPath.Split(new char[] { '\\' }).Last<string>());
137        }
138
139        public override object[] GetContextConstructorArguments(IConnectionInfo cxInfo)
140        {
141            if (string.IsNullOrEmpty(cxInfo.DatabaseInfo.CustomCxString))
142            {
143                return new object[0];
144            }
145            return new object[] { cxInfo.DatabaseInfo.CustomCxString };
146        }
147
148        public override ParameterDescriptor[] GetContextConstructorParameters(IConnectionInfo cxInfo)
149        {
150            if (string.IsNullOrEmpty(cxInfo.DatabaseInfo.CustomCxString))
151            {
152                return new ParameterDescriptor[0];
153            }
154            return new ParameterDescriptor[] { new ParameterDescriptor("param", "System.String") };
155        }
156
157        public override ICustomMemberProvider GetCustomDisplayMemberProvider(object objectToWrite)
158        {
159            if (objectToWrite == null)
160            {
161                return null;
162            }
163            if (!EntityFrameworkMemberProvider.IsEntity(objectToWrite.GetType()))
164            {
165                return null;
166            }
167            return new EntityFrameworkMemberProvider(objectToWrite);
168        }
169
170        private static Assembly GetEfAssembly(IConnectionInfo cxInfo)
171        {
172            if (_efAssembly != null)
173            {
174                return _efAssembly;
175            }
176            _efAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault<Assembly>(a => a.FullName.StartsWith("entityframework,", StringComparison.InvariantCultureIgnoreCase));
177            if (_efAssembly != null)
178            {
179                return _efAssembly;
180            }
181            string efPath = GetEfPath(cxInfo, false);
182            if (efPath == null)
183            {
184                return null;
185            }
186            if (efPath.Contains<char>(','))
187            {
188                return (_efAssembly = Assembly.Load(efPath));
189            }
190            return (_efAssembly = DataContextDriver.LoadAssemblySafely(efPath));
191        }
192
193        private static string GetEfPath(IConnectionInfo cxInfo, bool convertFullNameToGacPath)
194        {
195            string efVersion;
196            string customAssemblyPath = cxInfo.CustomTypeInfo.CustomAssemblyPath;
197            if (string.IsNullOrEmpty(customAssemblyPath))
198            {
199                return null;
200            }
201            try
202            {
203                string path = Path.Combine(Path.GetDirectoryName(customAssemblyPath), "EntityFramework.dll");
204                if (File.Exists(path))
205                {
206                    return path;
207                }
208            }
209            catch (ArgumentException)
210            {
211            }
212            if (customAssemblyPath == _lastEfPathInput)
213            {
214                return (convertFullNameToGacPath ? _lastEfPathGac : _lastEfPath);
215            }
216            _lastEfPath = null;
217            string shortName = Path.GetFileNameWithoutExtension(customAssemblyPath);
218            Assembly customAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault<Assembly>(a => a.GetName().Name.Equals(shortName, StringComparison.InvariantCultureIgnoreCase));
219            if (customAssembly != null)
220            {
221                efVersion = new EFVersionProber().GetEfVersion(customAssembly);
222            }
223            else
224            {
225                using (DomainIsolator isolator = new DomainIsolator("Probe EF version"))
226                {
227                    efVersion = isolator.GetInstance<EFVersionProber>().GetEfVersion(customAssemblyPath);
228                }
229            }
230            _lastEfPath = efVersion;
231            string str5 = _lastEfPathGac = GacResolver.FindPath(efVersion);
232            _lastEfPathInput = customAssemblyPath;
233            return (convertFullNameToGacPath ? str5 : efVersion);
234        }
235
236        private static string GetESqlCxString(object context)
237        {
238            return GetObjectContext(context).Connection.ConnectionString;
239        }
240
241        public override IDbConnection GetIDbConnection(IConnectionInfo cxInfo)
242        {
243            return GetIDbConnection(base.InstantiateBaseContext(cxInfo));
244        }
245
246        private static IDbConnection GetIDbConnection(object dbContext)
247        {
248            object obj2 = dbContext.GetType().GetProperty("Database").GetValue(dbContext, null);
249            return (IDbConnection) obj2.GetType().GetProperty("Connection").GetValue(obj2, null);
250        }
251
252        internal override string GetImageKey(IConnectionInfo r)
253        {
254            return "EF";
255        }
256
257        public override IEnumerable<string> GetNamespacesToAdd(IConnectionInfo cxInfo)
258        {
259            return new string[] { "System.Data.Entity", "System.Data.Entity.Infrastructure", "System.Data.Entity.Validation", "System.Data.EntityClient", "System.Data.Metadata.Edm", "System.Data.Objects", "System.Data.Objects.DataClasses" };
260        }
261
262        public override IEnumerable<string> GetNamespacesToRemove(IConnectionInfo cxInfo)
263        {
264            return new string[] { "System.Data.Linq", "System.Data.Linq.SqlClient" };
265        }
266
267        private static ObjectContext GetObjectContext(object context)
268        {
269            ObjectContext context2;
270            if (context == null)
271            {
272                return null;
273            }
274            Type type = context.GetType().GetInterface("System.Data.Entity.Infrastructure.IObjectContextAdapter");
275            try
276            {
277                context2 = (ObjectContext) type.GetProperty("ObjectContext").GetValue(context, null);
278            }
279            catch (Exception exception)
280            {
281                throw GetRealException(exception);
282            }
283            return context2;
284        }
285
286        public override DbProviderFactory GetProviderFactory(IConnectionInfo cxInfo)
287        {
288            DbConnection iDbConnection = GetIDbConnection(cxInfo) as DbConnection;
289            if (iDbConnection == null)
290            {
291                return null;
292            }
293            return DbProviderServices.GetProviderFactory(iDbConnection);
294        }
295
296        public static Exception GetRealException(Exception possiblyDistractingException)
297        {
298            Exception innerException = possiblyDistractingException;
299            while (innerException.InnerException != null)
300            {
301                if (innerException is TargetInvocationException)
302                {
303                    innerException = innerException.InnerException;
304                }
305                else
306                {
307                    if (!(innerException is ProviderIncompatibleException) || !(GetRealException(innerException.InnerException) is DbException))
308                    {
309                        return innerException;
310                    }
311                    innerException = innerException.InnerException;
312                }
313            }
314            return innerException;
315        }
316
317        public override List<ExplorerItem> GetSchema(IConnectionInfo cxInfo, Type t)
318        {
319            CheckEFAssemblyResolver(cxInfo);
320            object[] contextConstructorArguments = this.GetContextConstructorArguments(cxInfo);
321            return EntityFrameworkEdmReader.GetSchema(GetObjectContext(Activator.CreateInstance(t, contextConstructorArguments)));
322        }
323
324        public override void InitializeContext(IConnectionInfo cxInfo, object context, QueryExecutionManager executionManager)
325        {
326            CheckForUnpatchedCx(context);
327        }
328
329        private static void InstallEFResolver()
330        {
331            if (!_efResolverInstalled)
332            {
333                _efResolverInstalled = true;
334                AppDomain.CurrentDomain.AssemblyResolve += delegate (object sender, ResolveEventArgs args) {
335                    if (!(((args.Name == "EntityFramework, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") && !string.IsNullOrEmpty(_efDllPath)) && File.Exists(_efDllPath)))
336                    {
337                        return null;
338                    }
339                    return Assembly.LoadFrom(_efDllPath);
340                };
341            }
342        }
343
344        public static void PatchCxFactory(IConnectionInfo cxInfo)
345        {
346            if (!_cxFactoryPatched)
347            {
348                Assembly efAssembly = GetEfAssembly(cxInfo);
349                if (efAssembly != null)
350                {
351                    Type interfaceType = efAssembly.GetType("System.Data.Entity.Infrastructure.IDbConnectionFactory");
352                    if (interfaceType != null)
353                    {
354                        Type type = efAssembly.GetType("System.Data.Entity.Database");
355                        if (type != null)
356                        {
357                            PropertyInfo property = type.GetProperty("DefaultConnectionFactory", BindingFlags.Public | BindingFlags.Static);
358                            if (property != null)
359                            {
360                                object obj2 = property.GetValue(null, null);
361                                _cxFactoryPatched = true;
362                                if ((obj2 == null) || !(obj2.GetType().Name == "LINQPadDbConnectionFactory"))
363                                {
364                                    AppDomain currentDomain = AppDomain.CurrentDomain;
365                                    AssemblyName name = new AssemblyName("LINQPad.EntityFrameworkBridge");
366                                    TypeBuilder builder3 = currentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run).DefineDynamicModule("MainModule").DefineType("LINQPadDbConnectionFactory", TypeAttributes.Public);
367                                    builder3.AddInterfaceImplementation(interfaceType);
368                                    FieldBuilder field = builder3.DefineField("_innerFactory", interfaceType, FieldAttributes.Private);
369                                    ILGenerator iLGenerator = builder3.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { interfaceType }).GetILGenerator();
370                                    iLGenerator.Emit(OpCodes.Ldarg_0);
371                                    iLGenerator.Emit(OpCodes.Ldarg_1);
372                                    iLGenerator.Emit(OpCodes.Stfld, field);
373                                    iLGenerator.Emit(OpCodes.Ret);
374                                    iLGenerator = builder3.DefineMethod("CreateConnection", MethodAttributes.Virtual | MethodAttributes.Public, typeof(DbConnection), new Type[] { typeof(string) }).GetILGenerator();
375                                    iLGenerator.Emit(OpCodes.Ldarg_1);
376                                    iLGenerator.Emit(OpCodes.Ldarg_0);
377                                    iLGenerator.Emit(OpCodes.Ldfld, field);
378                                    iLGenerator.Emit(OpCodes.Call, typeof(EntityFrameworkFactoryConnectionHelper).GetMethod("CreateFactoryConnection", BindingFlags.Public | BindingFlags.Static));
379                                    iLGenerator.Emit(OpCodes.Ret);
380                                    object obj3 = Activator.CreateInstance(builder3.CreateType(), new object[] { obj2 });
381                                    property.SetValue(null, obj3, null);
382                                }
383                            }
384                        }
385                    }
386                }
387            }
388        }
389
390        public override bool ShowConnectionDialog(IConnectionInfo repository, bool isNewRepository)
391        {
392            using (DbContextCxForm form = new DbContextCxForm(repository))
393            {
394                return (form.ShowDialog() == DialogResult.OK);
395            }
396        }
397
398        public void Test(IConnectionInfo cxInfo)
399        {
400            CheckEFAssemblyResolver(cxInfo);
401            GetObjectContext(base.InstantiateBaseContext(cxInfo));
402        }
403
404        public override string Author
405        {
406            get
407            {
408                return "(built in)";
409            }
410        }
411
412        internal override string InternalID
413        {
414            get
415            {
416                return "EntityFrameworkDbContext";
417            }
418        }
419
420        internal override int InternalSortOrder
421        {
422            get
423            {
424                return 20;
425            }
426        }
427
428        internal override bool IsBuiltIn
429        {
430            get
431            {
432                return true;
433            }
434        }
435
436        public override string Name
437        {
438            get
439            {
440                return "Entity Framework DbContext POCO (4.1/4.2/4.3)";
441            }
442        }
443
444        private class EFVersionProber : MarshalByRefObject
445        {
446            public string GetEfVersion(Assembly customAssembly)
447            {
448                AssemblyName name = customAssembly.GetReferencedAssemblies().FirstOrDefault<AssemblyName>(a => a.Name.Equals("entityframework", StringComparison.InvariantCultureIgnoreCase));
449                return ((name == null) ? null : name.FullName);
450            }
451
452            public string GetEfVersion(string customAssemPath)
453            {
454                return this.GetEfVersion(Assembly.ReflectionOnlyLoadFrom(customAssemPath));
455            }
456        }
457    }
458}
459