private HelperClassesGenerationInfo CompileMissingClasses(DataTypeDescriptor dataTypeDescriptor, Dictionary <DataTypeDescriptor, IEnumerable <SqlDataTypeStoreDataScope> > allSqlDataTypeStoreDataScopes, Dictionary <SqlDataTypeStoreTableKey, StoreTypeInfo> fields, List <SqlDataTypeStoreDataScope> storeDataScopesToCompile, List <SqlDataTypeStoreDataScope> storeDataScopesAlreadyCompiled) { return(new HelperClassesGenerationInfo { GenerateCodeAction = codeGenerationBuilder => { var sqlDataProviderCodeBuilder = new SqlDataProviderCodeBuilder(_dataProviderContext.ProviderName, codeGenerationBuilder); sqlDataProviderCodeBuilder.AddDataType(dataTypeDescriptor, storeDataScopesToCompile); sqlDataProviderCodeBuilder.AddExistingDataType(dataTypeDescriptor, storeDataScopesAlreadyCompiled); }, PopulateFieldsAction = types => { foreach (SqlDataTypeStoreDataScope storeDataScope in storeDataScopesToCompile) { string dataContextFieldName = NamesCreator.MakeDataContextFieldName(storeDataScope.TableName); string helperClassFullName = NamesCreator.MakeSqlDataProviderHelperClassFullName( dataTypeDescriptor, storeDataScope.DataScopeName, storeDataScope.CultureName, _dataProviderContext.ProviderName); Type helperClass = types.Single(f => f.FullName == helperClassFullName); string entityClassFullName = NamesCreator.MakeEntityClassFullName( dataTypeDescriptor, storeDataScope.DataScopeName, storeDataScope.CultureName, _dataProviderContext.ProviderName); Type entityClass = types.Single(f => f.FullName == entityClassFullName); var storeTableKey = new SqlDataTypeStoreTableKey(storeDataScope.DataScopeName, storeDataScope.CultureName); fields[storeTableKey] = new StoreTypeInfo(dataContextFieldName, entityClass, helperClass); } foreach (SqlDataTypeStoreDataScope storeDataScope in storeDataScopesAlreadyCompiled) { string dataContextFieldName = NamesCreator.MakeDataContextFieldName(storeDataScope.TableName); string helperClassFullName = NamesCreator.MakeSqlDataProviderHelperClassFullName( dataTypeDescriptor, storeDataScope.DataScopeName, storeDataScope.CultureName, _dataProviderContext.ProviderName); Type helperClass = TryGetGeneratedType(helperClassFullName); string entityClassFullName = NamesCreator.MakeEntityClassFullName( dataTypeDescriptor, storeDataScope.DataScopeName, storeDataScope.CultureName, _dataProviderContext.ProviderName); Type entityClass = TryGetGeneratedType(entityClassFullName); var storeTableKey = new SqlDataTypeStoreTableKey(storeDataScope.DataScopeName, storeDataScope.CultureName); fields[storeTableKey] = new StoreTypeInfo(dataContextFieldName, entityClass, helperClass); } } }); }
/// <summary> /// Checks that tables related to specified data type included in current DataContext class, if not - compiles a new version of DataContext that contains them /// </summary> private HelperClassesGenerationInfo EnsureNeededTypes( DataTypeDescriptor dataTypeDescriptor, IEnumerable <SqlDataTypeStoreDataScope> sqlDataTypeStoreDataScopes, Dictionary <DataTypeDescriptor, IEnumerable <SqlDataTypeStoreDataScope> > allSqlDataTypeStoreDataScopes, Type dataContextClassType, out Dictionary <SqlDataTypeStoreTableKey, StoreTypeInfo> fields, ref bool dataContextRecompileNeeded, bool forceCompile = false) { lock (_lock) { // Getting the interface (ensuring that it exists) Type interfaceType = DataTypeTypesManager.GetDataType(dataTypeDescriptor); var storeDataScopesToCompile = new List <SqlDataTypeStoreDataScope>(); var storeDataScopesAlreadyCompiled = new List <SqlDataTypeStoreDataScope>(); fields = new Dictionary <SqlDataTypeStoreTableKey, StoreTypeInfo>(); foreach (SqlDataTypeStoreDataScope storeDataScope in sqlDataTypeStoreDataScopes) { string dataContextFieldName = NamesCreator.MakeDataContextFieldName(storeDataScope.TableName); FieldInfo dataContextFieldInfo = null; if (dataContextClassType != null) { dataContextFieldInfo = dataContextClassType.GetFields(BindingFlags.Public | BindingFlags.Instance) .SingleOrDefault(f => f.Name == dataContextFieldName); } string sqlDataProviderHelperClassFullName = NamesCreator.MakeSqlDataProviderHelperClassFullName(dataTypeDescriptor, storeDataScope.DataScopeName, storeDataScope.CultureName, _dataProviderContext.ProviderName); string entityClassName = NamesCreator.MakeEntityClassFullName(dataTypeDescriptor, storeDataScope.DataScopeName, storeDataScope.CultureName, _dataProviderContext.ProviderName); Type sqlDataProviderHelperClass = null, entityClass = null; try { sqlDataProviderHelperClass = TryGetGeneratedType(sqlDataProviderHelperClassFullName); entityClass = TryGetGeneratedType(entityClassName); forceCompile = forceCompile || CodeGenerationManager.IsRecompileNeeded(interfaceType, new[] { sqlDataProviderHelperClass, entityClass }); } catch (TypeLoadException) { forceCompile = true; } if (!forceCompile) { var storeTypeInfo = new StoreTypeInfo(dataContextFieldName, entityClass, sqlDataProviderHelperClass) { DataContextField = dataContextFieldInfo }; fields.Add(new SqlDataTypeStoreTableKey(storeDataScope.DataScopeName, storeDataScope.CultureName), storeTypeInfo); } if (dataContextFieldInfo == null) { dataContextRecompileNeeded = true; } if (forceCompile) { storeDataScopesToCompile.Add(storeDataScope); } else { storeDataScopesAlreadyCompiled.Add(storeDataScope); } } if (storeDataScopesToCompile.Any()) { dataContextRecompileNeeded = true; if (!dataTypeDescriptor.IsCodeGenerated) { // Building a new descriptor so generated classes take in account field changes dataTypeDescriptor = DynamicTypeManager.BuildNewDataTypeDescriptor(interfaceType); } return(CompileMissingClasses(dataTypeDescriptor, allSqlDataTypeStoreDataScopes, fields, storeDataScopesToCompile, storeDataScopesAlreadyCompiled)); } } return(null); }