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