Esempio n. 1
0
        public ActionResult UpdateContext(ContextViewModel postedModel)
        {
            MetadataModel metadata = TempData["Metadata"] as MetadataModel;

            IModelContext eavContext = metadata.CurrentContext;

            if (UpdateRequested)
            {
                eavContext.Name        = postedModel.Name;
                eavContext.DataName    = postedModel.DataName;
                eavContext.DisplayText = postedModel.DisplayText;

                foreach (ContainerViewModel containerModel in postedModel.Containers)
                {
                    eavContext.Containers.Single(it => it.ContainerID == containerModel.ID).Sequence = containerModel.Sequence;
                }
            }
            else if (eavContext.ObjectState == ObjectState.New && (String.IsNullOrWhiteSpace(eavContext.Name) || (String.IsNullOrWhiteSpace(eavContext.DataName))) && !eavContext.Containers.Any())
            {
                metadata.Contexts.Remove(eavContext);
            }

            TempData["Metadata"] = metadata;

            return(BuildResult(null, null, null, metadata.Contexts.Select(it => new { Value = it.ContextID, Text = it.Name })));
        }
Esempio n. 2
0
 private void UIElement_OnDrop(object sender, DragEventArgs e)
 {
     if (e.Data.GetDataPresent(DataFormats.FileDrop))
     {
         var files = (string[])e.Data.GetData(DataFormats.FileDrop);
         if (e.KeyStates == DragDropKeyStates.ShiftKey)
         {
             foreach (var file in files)
             {
                 var dir = new DirectoryInfo(file);
                 if (dir.Exists)
                 {
                     ContextViewModel.Destination = dir.FullName;
                     break;
                 }
                 var inf = new FileInfo(file);
                 if (inf.Exists && inf.Directory != null)
                 {
                     ContextViewModel.Destination = inf.Directory.FullName;
                     break;
                 }
             }
         }
         else
         {
             ContextViewModel.Action(files);
         }
     }
 }
Esempio n. 3
0
        public ContextView(ContextViewModel viewModel)
        {
            _context    = viewModel;
            DataContext = viewModel;
            InitializeComponent();

            _ = Task.Run(_context.InitializeAsync);
        }
        public void BusinessLogicViewModel_IsMetadataClassGenerationRequested_Property()
        {
            string tempFolder = UnitTestHelper.CreateTempFolder();

            try
            {
                Type   contextType  = typeof(DataTests.Northwind.LTS.NorthwindDataContext);
                string assemblyName = contextType.Assembly.GetName().Name;
                using (BusinessLogicViewModel model = new BusinessLogicViewModel(tempFolder, "FooClass", "C#", "ARootNamespace", assemblyName, new[] { contextType }, /* IVsHelp object */ null))
                {
                    ContextViewModel currentViewModel = model.CurrentContextViewModel;
                    Assert.IsNotNull(currentViewModel);
                    Assert.IsTrue(currentViewModel.Entities.Count() > 0);

                    // Verify we still cannot generate metadata classes even with a current context (until one entity is selected)
                    Assert.IsFalse(model.IsMetadataClassGenerationRequested, "Expect IsMetadataClassGenerationRequested to remain false until include an entity");

                    // Try to set it to true -- it should remain false as long as there are no entities included
                    model.IsMetadataClassGenerationRequested = true;
                    Assert.IsFalse(model.IsMetadataClassGenerationRequested, "Expect IsMetadataClassGenerationRequested to remain false even if try to set to true");

                    // Now include an entity and ensure we see event and can modify it
                    int sawPropertyChange      = 0;
                    int sawAllowPropertyChange = 0;
                    model.PropertyChanged += delegate(object sender, PropertyChangedEventArgs eventArgs)
                    {
                        if (eventArgs.PropertyName.Equals("IsMetadataClassGenerationRequested"))
                        {
                            ++sawPropertyChange;
                        }
                        if (eventArgs.PropertyName.Equals("IsMetadataClassGenerationAllowed"))
                        {
                            ++sawAllowPropertyChange;
                        }
                    };

                    // Now, include at least one entity and verify we are allowed to generate buddy classes
                    currentViewModel.Entities.First().IsIncluded = true;

                    // This should have raised property on model that enables the checkbox
                    Assert.AreEqual(1, sawAllowPropertyChange, "Failed to see property change event for IsMetadataClassGenerationAllowed after set it");
                    Assert.IsTrue(model.IsMetadataClassGenerationAllowed, "Expected to be able to toggle IsMetadataClassGenerationAllowed");

                    // But it should still be false -- we haven't asked to set it yet
                    Assert.IsFalse(model.IsMetadataClassGenerationRequested, "Expect IsMetadataClassGenerationRequested to remain false until explicitly set");

                    // Now set it.  It should now allow toggling, and we should see another event
                    model.IsMetadataClassGenerationRequested = true;
                    Assert.AreEqual(1, sawPropertyChange, "Failed to see property change event for IsMetadataClassGenerationRequested after set it");
                    Assert.IsTrue(model.IsMetadataClassGenerationRequested, "Expected to be able to toggle IsMetadataClassGenerationRequested");
                }
            }
            finally
            {
                Directory.Delete(tempFolder);
            }
        }
Esempio n. 5
0
 public ContextView(ContextViewModel viewModel)
 {
     InitializeComponent();
     DataContext      = ViewModel = viewModel;
     ViewModel.Close += (sender, eventArgs) =>
     {
         DialogResult = eventArgs.IsAccepted;
         Close();
     };
 }
Esempio n. 6
0
        public ActionResult ContextEditorDialog()
        {
            MetadataModel metadata = TempData["Metadata"] as MetadataModel;

            ContextViewModel contextModel = metadata.DialogStack.Pop() as ContextViewModel;

            TempData["Metadata"] = metadata;

            return(PartialView("ContextEditorDialog", contextModel));
        }
        public ActionResult Delete(int id)
        {
            var context   = _contextService.GetById(id);
            var viewModel = new ContextViewModel()
            {
                Id   = context.Id,
                Name = context.Name
            };

            return(View(viewModel));
        }
        public ActionResult Delete(ContextViewModel viewModel)
        {
            var context = new Context()
            {
                Id = viewModel.Id
            };

            _contextService.Delete(context);

            return(RedirectToAction("Index"));
        }
        public ActionResult CreateFirstContext(ContextViewModel contextViewModel)
        {
            var listCurrency = new CurrencyTypeService().GetAll();

            contextViewModel.CurrencyTypeSelectList = new SelectList(listCurrency, "Id", "Name");

            var listCountry = new CountryService().GetAll();

            contextViewModel.CountrySelectList = new SelectList(listCountry, "Id", "Name");

            return(View(contextViewModel));
        }
        public void BusinessLogicViewModel_Ctor_Many_Contexts()
        {
            Type[] contextTypes = new Type[] {
                typeof(DataTests.Northwind.LTS.NorthwindDataContext),
                typeof(NorthwindEntities),
                typeof(DataTests.Scenarios.EF.Northwind.NorthwindEntities_Scenarios),
                typeof(DataTests.Scenarios.LTS.Northwind.NorthwindScenarios),
                typeof(AdventureWorksEntities),
                typeof(DataTests.AdventureWorks.LTS.AdventureWorks),
            };

            string tempFolder = UnitTestHelper.CreateTempFolder();

            try
            {
                // Try the ctor that takes a type list
                using (BusinessLogicViewModel model = new BusinessLogicViewModel(tempFolder, "FooClass", "C#", "ARootNamespace", "AnAssemblyName", contextTypes, /* IVsHelp object */ null))
                {
                    ContextViewModel context = model.CurrentContextViewModel;
                    Assert.IsNotNull(context, "null context");
                    Assert.IsNotNull(model.ContextViewModels, "null context view models");
                    Assert.AreEqual(contextTypes.Length + 1, model.ContextViewModels.Count, "Expected this many contexts");

                    // Verify the first is the empty one
                    Assert.AreEqual("<empty Domain Service class>", model.ContextViewModels[0].Name, "Empty context should have been first");

                    // Verify they are sorted
                    for (int i = 2; i < model.ContextViewModels.Count; ++i)
                    {
                        string name1 = model.ContextViewModels[i - 1].Name;
                        string name2 = model.ContextViewModels[i].Name;
                        Assert.IsTrue(string.Compare(name1, name2, StringComparison.OrdinalIgnoreCase) < 0, "Expected " + name1 + " to collate less than " + name2);
                    }

                    // Cycle through each context to force it to load its entities
                    for (int i = 1; i < model.ContextViewModels.Count; ++i)
                    {
                        model.CurrentContextViewModel = model.ContextViewModels[i];
                        Assert.AreEqual(model.CurrentContextViewModel, model.ContextViewModels[i], "Failed to set current context");
                        IEnumerable <EntityViewModel> entities = model.CurrentContextViewModel.Entities;
                        Assert.IsTrue(entities.Any(), "Expected at least one entity in model " + model.CurrentContextViewModel.Name);
                    }
                }
            }
            finally
            {
                Directory.Delete(tempFolder);
            }
        }
        public ActionResult Index()
        {
            IEnumerable <Context>   listContext = _contextService.GetAll();
            List <ContextViewModel> viewModel   = new List <ContextViewModel>();

            foreach (var context in listContext)
            {
                var contextVM = new ContextViewModel();
                contextVM.Id   = context.Id;
                contextVM.Name = context.Name;

                viewModel.Add(contextVM);
            }

            return(View(viewModel));
        }
        public ViewResult Context(object pageModel)
        {
            var contextData = new ContextData
            {
                Primarylanguage  = "en",
                Model            = pageModel,
                AntiForgeryToken = string.Empty
            };

            var model = new ContextViewModel
            {
                ContextDataJson = this.jsonProvider.Serialize(contextData, true)
            };

            return(this.View(model));
        }
Esempio n. 13
0
 static void Set(ContextViewModel cs, bool enabled)
 {
     cs.Compress            = enabled;
     cs.CompressBz2         = enabled;
     cs.CompressDetails     = enabled;
     cs.CompressGz          = enabled;
     cs.CompressXz          = enabled;
     cs.Compress7z          = enabled;
     cs.CompressSfx         = enabled;
     cs.CompressZip         = enabled;
     cs.CompressZipPassword = enabled;
     cs.Extract             = enabled;
     cs.ExtractDesktop      = enabled;
     cs.ExtractMyDocuments  = enabled;
     cs.ExtractQuery        = enabled;
     cs.ExtractSource       = enabled;
 }
Esempio n. 14
0
        public ActionResult Create(UserViewModel userViewModel)
        {
            if (ModelState.IsValid)
            {
                var user = new User
                {
                    Name     = userViewModel.Name,
                    LastName = userViewModel.LastName,
                    Email    = userViewModel.Email,
                    Password = userViewModel.Password
                };

                var mainContext = new Context()
                {
                    UserId         = user.Id,
                    IsMainContext  = true,
                    Name           = string.Empty,
                    CountryId      = 1,
                    CurrencyTypeId = 1
                };

                user.AddNewContext(mainContext);

                _userService.Add(user);

                // Login into plataform - bacause of the Autorization (attribute)
                CookieUtil.SetAuthCookie(user.Id, user.Name, user.GetTheMainContextId());

                // Context - redirect (for update the main context)
                var contextViewModel = new ContextViewModel();
                contextViewModel.Id             = mainContext.Id;
                contextViewModel.IsMainContext  = true;
                contextViewModel.UserId         = user.Id;
                contextViewModel.CountryId      = 1;
                contextViewModel.CurrencyTypeId = 1;

                return(RedirectToAction("CreateFirstContext", "Context", contextViewModel));
            }
            else
            {
                SendModelStateErrors();
                return(View(userViewModel));
            }
        }
        public ContextViewModel Create(string selectedKey = "")
        {
            ContextViewModel viewModel = new ContextViewModel();

            List <ICounty>       counties       = _countyService.Get();
            List <IMunicipality> municipalities = _municipalityService.Get();

            counties.Sort((x, y) => x.Name.CompareTo(y.Name));
            municipalities.Sort((x, y) => x.Name.CompareTo(y.Name));

            counties.ForEach(c => viewModel.Counties.Add($"F{c.Id}", c.Name));

            int         count       = municipalities.Count;
            CultureInfo cultureInfo = new System.Globalization.CultureInfo("nb-NO");

            for (int i = 0; i < municipalities.Count; ++i)
            {
                if (i < count - 1 && municipalities[i].Name == municipalities[i + 1].Name)
                {
                    string county1 = _countyService.GetByMunicipalityId(municipalities[i].Id).Name;
                    string county2 = _countyService.GetByMunicipalityId(municipalities[i + 1].Id).Name;

                    if (string.Compare(county1, county2, cultureInfo, CompareOptions.None) > 0)
                    {
                        viewModel.Municipalities.Add($"M{municipalities[i + 1].Id}", $"{municipalities[i + 1].Name} i {county2}");
                        viewModel.Municipalities.Add($"M{municipalities[i].Id}", $"{municipalities[i].Name} i {county1}");
                    }
                    else
                    {
                        viewModel.Municipalities.Add($"M{municipalities[i].Id}", $"{municipalities[i].Name} i {county1}");
                        viewModel.Municipalities.Add($"M{municipalities[i + 1].Id}", $"{municipalities[i + 1].Name} i {county2}");
                    }
                    ++i;
                }
                else
                {
                    viewModel.Municipalities.Add($"M{municipalities[i].Id}", municipalities[i].Name);
                }
            }
            viewModel.SelectedKey = selectedKey;

            return(viewModel);
        }
Esempio n. 16
0
        public ActionResult AddRootContainer(ContextViewModel postedModel)
        {
            MetadataModel metadata = TempData["Metadata"] as MetadataModel;

            postedModel.FixupContainerOrder();
            metadata.DialogStack.Push(postedModel);

            IModelRootContainer eavContainer = objectFactory.Create <EAV.Model.IModelRootContainer>();

            eavContainer.ContainerID = metadata.NextContainerID;
            eavContainer.Context     = metadata.CurrentContext;
            eavContainer.Sequence    = metadata.CurrentContext.Containers.Max(it => it.Sequence) + 1;

            metadata.DialogStack.Push(new ContainerViewModel(eavContainer));

            TempData["Metadata"] = metadata;

            return(BuildResult("Container Editor", Url.Content("~/Metadata/ContainerEditorDialog"), Url.Content("~/Metadata/UpdateRootContainer"), null));
        }
        private void SetAuthentication(Spartan_User_Core UserDetails)
        {
            // create instance of context view model
            ContextViewModel CM = new ContextViewModel();

            // set logged in values with context view model to store values with cookies
            CM.Email    = UserDetails.Spartan_Users[0].Email;
            CM.Id       = UserDetails.Spartan_Users[0].Id;
            CM.Id_User  = UserDetails.Spartan_Users[0].Id_User;
            CM.Password = UserDetails.Spartan_Users[0].Password;
            CM.Role     = UserDetails.Spartan_Users[0].Role;
            CM.Status   = UserDetails.Spartan_Users[0].Status;
            CM.Name     = UserDetails.Spartan_Users[0].Name;
            CM.UserName = UserDetails.Spartan_Users[0].Username;

            AuthenticationSerialize serialiseAuth = new AuthenticationSerialize();

            UserContextViewModel userContext = new UserContextViewModel();

            userContext.CurrentUser   = CM;
            serialiseAuth.UserContext = userContext;
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            string userData = serializer.Serialize(serialiseAuth);

            // set login cookie time for user
            var tenDaysFromNow = DateTime.UtcNow.AddMinutes(Convert.ToInt32(ConfigurationManager.AppSettings["SessionTimeOut"]));

            // set form authentication ticket with logged int user values
            FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                1,
                serialiseAuth.UserContext.CurrentUser.UserName + " " + serialiseAuth.UserContext.CurrentUser.UserName,
                DateTime.Now,
                tenDaysFromNow,
                false,
                userData);

            string     encTicket = FormsAuthentication.Encrypt(authTicket);
            HttpCookie faCookie  = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);

            // Add values of user with browser cookie
            Response.Cookies.Add(faCookie);
        }
Esempio n. 18
0
        public ActionResult DeleteRootContainer(ContextViewModel postedModel)
        {
            MetadataModel metadata = TempData["Metadata"] as MetadataModel;

            metadata.DialogStack.Push(postedModel);

            IModelRootContainer eavContainer = FindContainer(metadata.CurrentContext.Containers, ID) as IModelRootContainer;

            if (eavContainer.ObjectState != ObjectState.New)
            {
                eavContainer.MarkDeleted();
            }
            else
            {
                metadata.CurrentContext.Containers.Remove(eavContainer);
            }

            TempData["Metadata"] = metadata;

            return(BuildResult("Context Editor", Url.Content("~/Metadata/ContextEditorDialog"), Url.Content("~/Metadata/UpdateContext"), null));
        }
        public void BusinessLogicViewModel_Ctor_One_Context()
        {
            string tempFolder = UnitTestHelper.CreateTempFolder();

            try
            {
                // Try the ctor that takes a type list
                using (BusinessLogicViewModel model = new BusinessLogicViewModel(tempFolder, "FooClass", "C#", "ARootNamespace", "AnAssemblyName", new Type[] { typeof(DataTests.Northwind.LTS.NorthwindDataContext) }, /* IVsHelp object */ null))
                {
                    ContextViewModel context = model.CurrentContextViewModel;
                    Assert.IsNotNull(context, "null context");
                    Assert.IsNotNull(model.ContextViewModels, "null context view models");
                    Assert.AreEqual(2, model.ContextViewModels.Count, "Expected 2 contexts");
                    Assert.AreEqual("NorthwindDataContext (LINQ to SQL)", model.CurrentContextViewModel.Name, "Current context had wrong name");
                }
            }
            finally
            {
                Directory.Delete(tempFolder);
            }
        }
        public ActionResult Update(ContextViewModel contextViewModel)
        {
            if (ModelState.IsValid)
            {
                var context = new Context();
                context.Id             = contextViewModel.Id;
                context.Name           = contextViewModel.Name;
                context.IsMainContext  = contextViewModel.IsMainContext;
                context.CurrencyTypeId = contextViewModel.CurrencyTypeId;
                context.CountryId      = contextViewModel.CountryId;
                context.UserId         = GetCurrentUserId();

                _contextService.AddOrUpdate(context);

                return(RedirectToAction("Index", "Dashboard"));
            }
            else
            {
                SendModelStateErrors();
                return(View(contextViewModel));
            }
        }
Esempio n. 21
0
        public ActionResult EditRootContainer(ContextViewModel postedModel)
        {
            MetadataModel metadata = TempData["Metadata"] as MetadataModel;

            postedModel.FixupContainerOrder();
            metadata.DialogStack.Push(postedModel);

            IModelRootContainer eavContainer = FindContainer(metadata.CurrentContext.Containers, ID) as IModelRootContainer;

            // TODO: Check state after loading metadata, verify that Modified doesn't go away if set
            if (eavContainer.ObjectState != ObjectState.Deleted && eavContainer.ObjectState != ObjectState.New && !eavContainer.ChildContainers.Any() && !eavContainer.Attributes.Any())
            {
                eavClient.LoadMetadata(eavContainer);
            }

            metadata.DialogStack.Push(new ContainerViewModel(eavContainer)
            {
                Existing = true
            });

            TempData["Metadata"] = metadata;

            return(BuildResult("Container Editor", Url.Content("~/Metadata/ContainerEditorDialog"), Url.Content("~/Metadata/UpdateRootContainer"), null));
        }
Esempio n. 22
0
        public void Generate()
        {
            const string          setFileName     = "set.hbs";
            const string          contextFileName = "context.hbs";
            Func <object, string> templateSet;
            Func <object, string> templateContext;

            try
            {
                var setTemplate = File.ReadAllText(Path.Combine(_options.TemplatesDirectory, setFileName));
                templateSet = Handlebars.Compile(setTemplate);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error compiling Handlebars template {setFileName}: {ex.Message}");
                return;
            }
            try
            {
                var tableContext = File.ReadAllText(Path.Combine(_options.TemplatesDirectory, contextFileName));
                templateContext = Handlebars.Compile(tableContext);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error compiling Handlebars template {contextFileName}: {ex.Message}");
                return;
            }

            WriteLine("Templates are ready");

            using (var connection = new SqlConnection(_options.ConnectionString))
            {
                connection.Open();
                WriteLine("Connected to the database");

                var fkDefinitions = connection.ReadObjects <FkDefinition>(SchemaSql.ForeignKeysSql);
                WriteLine("Foreign keys information received");

                var keyColumns = connection.ReadObjects <KeyColumnDefinition>(SchemaSql.KeyColumnsSql);
                WriteLine("Primary keys information received");

                var tables = connection.ReadObjects <EntityDefinition>(SchemaSql.TablesSql);
                WriteLine("Tables information received");

                var views = connection.ReadObjects <EntityDefinition>(SchemaSql.ViewsSql);
                WriteLine("Views information received");

                var tablesColumns = connection.ReadObjects <ColumnDefinition>(SchemaSql.TableColumnsSql);
                WriteLine("Tables columns information received");

                var viewsColumns = connection.ReadObjects <ColumnDefinition>(SchemaSql.ViewColumnsSql);
                WriteLine("Views columns information received");

                var entityViewModels = new List <EntityViewModel>();

                ScaffoldObjects(entityViewModels, tables, tablesColumns, keyColumns, fkDefinitions, _options.IgnoreTables);

                ScaffoldObjects(entityViewModels, views, viewsColumns, null, null, _options.IgnoreViews);

                foreach (var foreignKey in fkDefinitions)
                {
                    var originTable = entityViewModels.SingleOrDefault(x =>
                                                                       x.SchemaName == foreignKey.PkSchema && x.EntityName == foreignKey.PkTable);

                    var foreignTable = entityViewModels.SingleOrDefault(x =>
                                                                        x.SchemaName == foreignKey.FkSchema && x.EntityName == foreignKey.FkTable);

                    if (originTable != null && foreignTable != null)
                    {
                        var fkColumn = foreignKey.FkColumn;

                        var propertyName = removeIdRegex.Replace(fkColumn, m => m.Groups["content"].Value).TrimEnd('_');
                        if (_options.ForeignPropertyRegex != null)
                        {
                            propertyName = Regex.Match(foreignKey.FkName, _options.ForeignPropertyRegex, RegexOptions.Singleline).Groups["PropertyName"].Value;
                            propertyName = propertyName.Replace("_", string.Empty);
                            if (propertyName.EndsWith("Id") || propertyName.EndsWith("ID"))
                            {
                                propertyName = propertyName.Substring(0, propertyName.Length - 2);
                            }
                        }

                        var inversePropertyName = propertyName.ReplaceFirstOccurrance(originTable.EntityName, foreignTable.EntityName);
                        inversePropertyName = StringHelper.Pluralize(inversePropertyName);

                        if (originTable == foreignTable)
                        {
                            inversePropertyName = "Inverse" + propertyName;
                        }

                        var foreignKeyViewModel = foreignKey.CloneCopy <FkDefinition, ForeignKeyViewModel>();
                        foreignKeyViewModel.PropertyName        = propertyName;
                        foreignKeyViewModel.InversePropertyName = inversePropertyName;
                        foreignTable.ForeignKeys.Add(foreignKeyViewModel);

                        var InverseKeyViewModel = foreignKey.CloneCopy <FkDefinition, ForeignKeyViewModel>();
                        InverseKeyViewModel.PropertyName        = inversePropertyName;
                        InverseKeyViewModel.InversePropertyName = propertyName;
                        originTable.InverseKeys.Add(InverseKeyViewModel);
                    }
                }

                var modelsDirectory = Path.Combine(_options.Directory, _options.ModelsPath);
                Directory.CreateDirectory(modelsDirectory);

                foreach (var tableViewModel in entityViewModels)
                {
                    var setResult = templateSet(tableViewModel);
                    File.WriteAllText(Path.Combine(modelsDirectory, tableViewModel.EntityName + ".cs"), setResult);
                }

                var contextViewModel = new ContextViewModel
                {
                    ContextName = _options.ContextName,
                    Namespace   = _options.Namespace,
                    Entities    = entityViewModels
                };
                var contextResult = templateContext(contextViewModel);
                File.WriteAllText(Path.Combine(modelsDirectory, contextViewModel.ContextName + ".cs"), contextResult);
            }
        }
 /// <summary>
 /// Called when [new geo context command].
 /// </summary>
 private void OnNewGeoContextCommand()
 {
     IsRegionContextVisible = true;
     ContextViewModel.Refresh();
 }
Esempio n. 24
0
        public void Generate()
        {
            const string          setFileName     = "set.hbs";
            const string          contextFileName = "context.hbs";
            Func <object, string> templateSet;
            Func <object, string> templateContext;

            try
            {
                var setTemplate = File.ReadAllText(Path.Combine(_options.TemplatesDirectory, setFileName));
                templateSet = Handlebars.Compile(setTemplate);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error compiling Handlebars template {setFileName}: {ex.Message}");
                return;
            }
            try
            {
                var tableContext = File.ReadAllText(Path.Combine(_options.TemplatesDirectory, contextFileName));
                templateContext = Handlebars.Compile(tableContext);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error compiling Handlebars template {contextFileName}: {ex.Message}");
                return;
            }

            WriteLine("Templates are ready");

            using (var connection = new SqlConnection(_options.ConnectionString))
            {
                connection.Open();
                WriteLine("Connected to the database");

                var fkDefinitionsSource = connection.ReadObjects <FkDefinitionSource>(SchemaSql.ForeignKeysSql);
                var fkDefinitions       =
                    (from s in fkDefinitionsSource
                     group s by new { s.PkSchema, s.FkSchema, s.FkTable, s.PkTable, s.FkName, s.PkName, s.MatchOption, s.UpdateRule, s.DeleteRule }
                     into sGroup
                     select new FkDefinition
                {
                    PkSchema = sGroup.Key.PkSchema,
                    FkSchema = sGroup.Key.FkSchema,
                    PkTable = sGroup.Key.PkTable,
                    FkTable = sGroup.Key.FkTable,
                    PkName = sGroup.Key.PkName,
                    FkName = sGroup.Key.FkName,
                    MatchOption = sGroup.Key.MatchOption,
                    DeleteRule = sGroup.Key.DeleteRule,
                    UpdateRule = sGroup.Key.UpdateRule,
                    PkColumns = sGroup.OrderBy(x => x.PkOrdinalPosition).Select(x => x.PkColumn).ToList(),
                    FkColumns = sGroup.OrderBy(x => x.FkOrdinalPosition).Select(x => x.FkColumn).ToList()
                }).ToList();

                WriteLine("Foreign keys information received");

                var keyColumns = connection.ReadObjects <KeyColumnDefinition>(SchemaSql.KeyColumnsSql);
                WriteLine("Primary keys information received");

                var tables = connection.ReadObjects <EntityDefinition>(SchemaSql.TablesSql);
                WriteLine("Tables information received");

                var views = connection.ReadObjects <EntityDefinition>(SchemaSql.ViewsSql);
                WriteLine("Views information received");

                var tablesColumns = connection.ReadObjects <ColumnDefinition>(SchemaSql.TableColumnsSql);
                WriteLine("Tables columns information received");

                var viewsColumns = connection.ReadObjects <ColumnDefinition>(SchemaSql.ViewColumnsSql);
                WriteLine("Views columns information received");

                var defaultSchemaName = connection.ReadObjects <SchemaDefinition>(SchemaSql.DefaultSchemaSql).First().SchemaName;

                var entityViewModels = new List <EntityViewModel>();

                ScaffoldObjects(entityViewModels, tables, tablesColumns, keyColumns, fkDefinitions, _options.IgnoreTables, defaultSchemaName);

                ScaffoldObjects(entityViewModels, views, viewsColumns, null, null, _options.IgnoreViews, defaultSchemaName);

                var pKeys =
                    (from pk in keyColumns
                     group pk by new { pk.TableSchema, pk.TableName, pk.KeyName }
                     into pkGroup
                     select new
                {
                    pkGroup.Key.TableSchema,
                    pkGroup.Key.TableName,
                    Columns = pkGroup.OrderBy(x => x.KeyOrder).Select(x => x.ColumnName).ToList()
                }).ToDictionary(x => $"{x.TableSchema}.{x.TableName}", x => x.Columns);

                foreach (var foreignKey in fkDefinitions)
                {
                    var originTable = entityViewModels.SingleOrDefault(x =>
                                                                       x.SchemaName == foreignKey.PkSchema && x.EntityName == foreignKey.PkTable);

                    var foreignTable = entityViewModels.SingleOrDefault(x =>
                                                                        x.SchemaName == foreignKey.FkSchema && x.EntityName == foreignKey.FkTable);

                    var isOneToOne = false;
                    //Check one-2-one in case matched columns names and theirs orders
                    var originTableFullName  = $"{foreignKey.PkSchema}.{foreignKey.PkTable}";
                    var foreignTableFullName = $"{foreignKey.FkSchema}.{foreignKey.FkTable}";
                    if (pKeys.ContainsKey(originTableFullName) && pKeys.ContainsKey(foreignTableFullName))
                    {
                        var pKeyOrigin  = pKeys[originTableFullName];
                        var pKeyForeign = pKeys[foreignTableFullName];
                        if (foreignKey.PkColumns.Count == foreignKey.FkColumns.Count && foreignKey.PkColumns.Count == pKeyOrigin.Count && foreignKey.PkColumns.Count == pKeyForeign.Count)
                        {
                            isOneToOne = true;
                            for (var i = 0; i < pKeyOrigin.Count; i++)
                            {
                                if (pKeyOrigin[i] == foreignKey.PkColumns[i] && pKeyForeign[i] == foreignKey.FkColumns[i])
                                {
                                    continue;
                                }
                                isOneToOne = false;
                                break;
                            }
                        }
                    }

                    if (originTable != null && foreignTable != null)
                    {
                        var propertyName = string.Empty;
                        foreach (var fkColumn in foreignKey.FkColumns)
                        {
                            propertyName = RemoveIdRegex.Replace(fkColumn, m => m.Groups["content"].Value).TrimEnd('_');
                        }

                        if (_options.ForeignPropertyRegex != null)
                        {
                            propertyName = Regex.Match(foreignKey.FkName, _options.ForeignPropertyRegex, RegexOptions.Singleline).Groups["PropertyName"].Value;
                            propertyName = propertyName.Replace("_", string.Empty);
                            if (propertyName.EndsWith("Id") || propertyName.EndsWith("ID"))
                            {
                                propertyName = propertyName.Substring(0, propertyName.Length - 2);
                            }
                        }

                        var inversePropertyName = propertyName.ReplaceFirstOccurrance(originTable.EntityName, foreignTable.EntityName);
                        if (!isOneToOne)
                        {
                            inversePropertyName = StringHelper.Pluralize(inversePropertyName);
                        }

                        if (originTable == foreignTable)
                        {
                            inversePropertyName = "Inverse" + propertyName;
                        }

                        var foreignKeyViewModel = foreignKey.CloneCopy <FkDefinition, ForeignKeyViewModel>();
                        foreignKeyViewModel.PropertyName        = propertyName;
                        foreignKeyViewModel.InversePropertyName = inversePropertyName;
                        foreignKeyViewModel.InverseEntityName   = originTable.EntityName;
                        foreignKeyViewModel.IsOneToOne          = isOneToOne;
                        foreignTable.ForeignKeys.Add(foreignKeyViewModel);

                        var inverseKeyViewModel = foreignKey.CloneCopy <FkDefinition, ForeignKeyViewModel>();
                        inverseKeyViewModel.PropertyName        = inversePropertyName;
                        inverseKeyViewModel.InversePropertyName = propertyName;
                        foreignKeyViewModel.InverseEntityName   = foreignTable.EntityName;
                        inverseKeyViewModel.IsOneToOne          = isOneToOne;
                        originTable.InverseKeys.Add(inverseKeyViewModel);
                    }
                }

                var modelsDirectory = Path.Combine(_options.Directory, _options.ModelsPath);
                Directory.CreateDirectory(modelsDirectory);

                foreach (var tableViewModel in entityViewModels)
                {
                    var setResult = templateSet(tableViewModel);
                    File.WriteAllText(Path.Combine(modelsDirectory, tableViewModel.EntityName + ".cs"), setResult);
                }

                var contextViewModel = new ContextViewModel
                {
                    ContextName = _options.ContextName,
                    Namespace   = _options.Namespace,
                    Entities    = entityViewModels
                };
                var contextResult = templateContext(contextViewModel);
                File.WriteAllText(Path.Combine(modelsDirectory, contextViewModel.ContextName + ".cs"), contextResult);
            }
        }
Esempio n. 25
0
 public ListViewPage()
 {
     InitializeComponent();
     this.BindingContext = viewModel = new ContextViewModel();
 }
        private void ValidateCodeGen(string language, Type contextType, string bizLogicFileBase, IEnumerable <string> references, bool oDataEndpoint, string rootNamespace, string namespaceName)
        {
#if UPDATE_BASELINES
            bool updateBaselines = true;
#else
            bool updateBaselines = false;
#endif
            string projectDir = Path.Combine(TestHelper.GetProjectDir(), @"Baselines");
            string extension  = TestHelper.ExtensionFromLanguage(language);

            string bizLogicBaseName   = bizLogicFileBase + extension;
            string buddyClassBaseName = bizLogicFileBase + ".metadata" + extension;

            string bizLogicFilePath   = Path.Combine(projectDir, bizLogicBaseName);
            string buddyClassFilePath = Path.Combine(projectDir, buddyClassBaseName);

            string generatedBizLogicFileName = Path.GetTempFileName();

            string className    = bizLogicFileBase;
            string assemblyName = (contextType == null) ? "NoAssembly" : contextType.Assembly.GetName().Name;

            Type[] contextTypes = (contextType == null) ? Array.Empty <Type>() : new Type[] { contextType };

            using (BusinessLogicViewModel model = new BusinessLogicViewModel(projectDir, className, language, rootNamespace, assemblyName, contextTypes, /* IVsHelp object */ null))
            {
                // Always get the default, but will have 2 if specified a type
                int expectedCount = contextType == null ? 1 : 2;

                Assert.AreEqual(expectedCount, model.ContextViewModels.Count, "Expected this many view models");

                ContextViewModel expectedViewModel = contextType == null ? model.ContextViewModels[0] : model.ContextViewModels[1];
                Assert.AreEqual(expectedViewModel, model.CurrentContextViewModel, "current not as expected");

                model.CurrentContextViewModel.IsODataEndpointEnabled = oDataEndpoint;

                // Select entities first to allow buddy class code-gen
                foreach (EntityViewModel entity in model.CurrentContextViewModel.Entities)
                {
                    entity.IsIncluded = true;
                    entity.IsEditable = true;
                }

                // Don't generate buddy classes for empty model
                model.IsMetadataClassGenerationRequested = contextType != null;

                // Generate the business logic class
                GeneratedCode generatedCode = model.GenerateBusinessLogicClass(namespaceName);
                File.AppendAllText(generatedBizLogicFileName, generatedCode.SourceCode);
                TestHelper.AssertReferenceListContains(references, generatedCode.References, true);

                // Generate the buddy class
                // Note: we pass in an optional "Buddy" suffix to both the namespace and class names
                // because the compiler would reject an attempt to use 'partial class' on an already
                // compiled class.  We put it in a separate namespace because we still need to import
                // the entity's real namespace, and they cannot be the same.
                //
                string generatedBuddyFileName = null;
                if (model.IsMetadataClassGenerationRequested)
                {
                    generatedBuddyFileName = Path.GetTempFileName();
                    generatedCode          = model.GenerateMetadataClasses("Buddy");
                    File.AppendAllText(generatedBuddyFileName, generatedCode.SourceCode);
                }

#if !UPDATE_BASELINES
                // See if both files compile clean against the current project
                string[] files = (model.IsMetadataClassGenerationRequested
                                    ? new string[] { generatedBizLogicFileName, generatedBuddyFileName }
                                    : new string[] { generatedBizLogicFileName });
                this.CompileGeneratedCode(TestHelper.GetProjectPath(), files, language);
#endif

                // Compare files against known baselines.
                // Optionally allow update of baselines rather than comparison
                TestHelper.ValidateFilesEqual(generatedBizLogicFileName, bizLogicFilePath, updateBaselines);

                if (model.IsMetadataClassGenerationRequested)
                {
                    TestHelper.ValidateFilesEqual(generatedBuddyFileName, buddyClassFilePath, updateBaselines);
                }

                // Clean up files.  Won't get here unless test passes
                File.Delete(generatedBizLogicFileName);

                if (model.IsMetadataClassGenerationRequested)
                {
                    File.Delete(generatedBuddyFileName);
                }
            }
        }
        public void Generate()
        {
            const string          setFileName     = "set.hbs";
            const string          contextFileName = "context.hbs";
            Func <object, string> templateSet;
            Func <object, string> templateContext;
            var fksPresetList                      = new List <FkPresetDefinition>();
            var tablesColumnsSettingsList          = new List <ObjectColumnsSettingModel>();
            var viewsColumnsSettingsList           = new List <ObjectColumnsSettingModel>();
            var fkPropertyDisplayNamesSettingsList = new List <FkPropertyDisplayNameDefinition>();
            var entityPluralizeNameSettingsList    = new List <EntityPluralizeNameDefinition>();

            Handlebars.RegisterHelper("TableContainsAllColumns", HBSHelper.TableContainsAllColumns);

            try
            {
                var setTemplate = File.ReadAllText(Path.Combine(_options.TemplatesDirectory, setFileName));
                templateSet = Handlebars.Compile(setTemplate);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error compiling Handlebars template {setFileName}: {ex.Message}");
                return;
            }
            try
            {
                var tableContext = File.ReadAllText(Path.Combine(_options.TemplatesDirectory, contextFileName));
                templateContext = Handlebars.Compile(tableContext);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error compiling Handlebars template {contextFileName}: {ex.Message}");
                return;
            }
            if (!string.IsNullOrEmpty(_options.CustomSettingsJsonPath))
            {
                try
                {
                    var customSettingsJsonString = Path.Combine(_options.CustomSettingsJsonPath);
                    var customSettingsJsonObject = JObject.Parse(File.ReadAllText(customSettingsJsonString));
                    var foreignKeys                    = (JObject)customSettingsJsonObject.GetValue("ForeignKeys");
                    var tablesColumnsSettings          = (JObject)customSettingsJsonObject.GetValue("TablesColumns");
                    var viewsColumnsSettings           = (JObject)customSettingsJsonObject.GetValue("ViewsColumns");
                    var foreignKeyPropertyDisplayNames = (JArray)customSettingsJsonObject.GetValue("FKPropertyNames");
                    var entityPluralizeNameSettings    = (JArray)customSettingsJsonObject.GetValue("EntityPluralizedNames");

                    fksPresetList                      = GetForeignKeysPresetList(foreignKeys);
                    tablesColumnsSettingsList          = GetObjectsColumnsSettingsList(tablesColumnsSettings);
                    viewsColumnsSettingsList           = GetObjectsColumnsSettingsList(viewsColumnsSettings);
                    fkPropertyDisplayNamesSettingsList = GetFkPropertyDisplayNamesSettingsList(foreignKeyPropertyDisplayNames);
                    entityPluralizeNameSettingsList    = GetEntityPluralizedNameSettingsList(entityPluralizeNameSettings);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error loading CustomSettings json file: {ex.Message}");
                    return;
                }
            }

            WriteLine("Templates are ready");

            var fkNamesSkipList = fksPresetList.Where(x => x.FkPropertyNames == null).Select(x => x.ForeignKeyName).ToList();


            using (var connection = new SqlConnection(_options.ConnectionString))
            {
                connection.Open();
                WriteLine("Connected to the database");

                var fkDefinitionsSource = connection.ReadObjects <FkDefinitionSource>(SchemaSql.ForeignKeysSql);
                var fkDefinitions       =
                    (from s in fkDefinitionsSource.Where(x => !fkNamesSkipList.Contains(x.FkName))
                     group s by new { s.PkSchema, s.FkSchema, s.FkTable, s.PkTable, s.FkName, s.PkName, s.MatchOption, s.UpdateRule, s.DeleteRule }
                     into sGroup
                     select new FkDefinition
                {
                    PkSchema = sGroup.Key.PkSchema,
                    FkSchema = sGroup.Key.FkSchema,
                    PkTable = sGroup.Key.PkTable,
                    FkTable = sGroup.Key.FkTable,
                    PkName = sGroup.Key.PkName,
                    FkName = sGroup.Key.FkName,
                    MatchOption = sGroup.Key.MatchOption,
                    DeleteRule = sGroup.Key.DeleteRule,
                    UpdateRule = sGroup.Key.UpdateRule,
                    PkColumns = sGroup.OrderBy(x => x.PkOrdinalPosition).Select(x => x.PkColumn).ToList(),
                    PkColumnDisplayNames = sGroup.OrderBy(x => x.PkOrdinalPosition).Select(x => PropertyHelper.GetColumnNameToDisplay(x.PkColumn, sGroup.Key.PkTable, tablesColumnsSettingsList)).ToList(),
                    FkColumns = sGroup.OrderBy(x => x.FkOrdinalPosition).Select(x => x.FkColumn).ToList(),
                    FkColumnDisplayNames = sGroup.OrderBy(x => x.FkOrdinalPosition).Select(x => PropertyHelper.GetColumnNameToDisplay(x.FkColumn, sGroup.Key.FkTable, tablesColumnsSettingsList)).ToList()
                }).ToList();

                WriteLine("Foreign keys information received");

                var keyColumns = connection.ReadObjects <KeyColumnDefinition>(SchemaSql.KeyColumnsSql);
                WriteLine("Primary keys information received");

                var tables = connection.ReadObjects <EntityDefinition>(SchemaSql.TablesSql);
                WriteLine("Tables information received");

                var views = connection.ReadObjects <EntityDefinition>(SchemaSql.ViewsSql);
                WriteLine("Views information received");

                var tablesColumns = connection.ReadObjects <ColumnDefinition>(string.Format(SchemaSql.TableColumnsSql, _options.ExtendedPropertyTypeName));
                WriteLine("Tables columns information received");

                var viewsColumns = connection.ReadObjects <ColumnDefinition>(string.Format(SchemaSql.ViewColumnsSql, _options.ExtendedPropertyTypeName));
                WriteLine("Views columns information received");

                var spDefinitions = new List <StoredObjectDefinition>();
                if (_options.GenerateStoredProcedures)
                {
                    spDefinitions = GetStoredObjectsDefinition(connection, SchemaSql.StoredProcedureParametersSql, false, _options.IgnoreStoredProcedure);
                    WriteLine("Stored procedures parameters information received");

                    foreach (var sp in spDefinitions)
                    {
                        WriteLine($"Reading schema for {sp.Schema}.{sp.Name}");
                        var spSetDefinition = string.Format(SchemaSql.StoredProcedureSetSql, sp.Schema, sp.Name);
                        var columns         = connection.ReadObjects <StoredObjectSetColumn>(spSetDefinition);
                        sp.Columns = columns.Where(x => !string.IsNullOrEmpty(x.Name) && ColumnValidRegex.IsMatch(x.Name)).ToList();
                    }
                }

                var tvfDefinitions = new List <StoredObjectDefinition>();

                if (_options.GenerateTableValuedFunctions)
                {
                    tvfDefinitions = GetStoredObjectsDefinition(connection, SchemaSql.TableValueFunctionParametersSql, true, _options.IgnoreTableValuedFunctions);
                    WriteLine("Table valued functions parameters information received");

                    var tvfColumns = connection.ReadObjects <TableValuedColumn>(SchemaSql.TableValueFunctionColumnsSql);
                    WriteLine("Table valued functions parameters information received");
                    foreach (var tvf in tvfDefinitions)
                    {
                        tvf.Columns = tvfColumns
                                      .Where(c => c.Schema == tvf.Schema && c.FunctionName == tvf.Name)
                                      .Cast <StoredObjectSetColumn>().ToList();
                    }
                }

                var defaultSchemaName = connection.ReadObjects <SchemaDefinition>(SchemaSql.DefaultSchemaSql).First().SchemaName;

                var entityViewModels = new List <EntityViewModel>();

                ScaffoldEntities(entityViewModels, tables, tablesColumns, keyColumns, fkDefinitions, _options.IgnoreTables, _options.AllowedTables, tablesColumnsSettingsList, entityPluralizeNameSettingsList, defaultSchemaName);

                ScaffoldEntities(entityViewModels, views, viewsColumns, null, null, _options.IgnoreViews, null, viewsColumnsSettingsList, entityPluralizeNameSettingsList, defaultSchemaName);

                var pKeys =
                    (from pk in keyColumns
                     group pk by new { pk.TableSchema, pk.TableName, pk.KeyName }
                     into pkGroup
                     select new
                {
                    pkGroup.Key.TableSchema,
                    pkGroup.Key.TableName,
                    Columns = pkGroup.OrderBy(x => x.KeyOrder).Select(x => x.ColumnName).ToList()
                }).ToDictionary(x => $"{x.TableSchema}.{x.TableName}", x => x.Columns);

                foreach (var foreignKey in fkDefinitions)
                {
                    var originTable = entityViewModels.SingleOrDefault(x =>
                                                                       x.SchemaName == foreignKey.PkSchema && x.EntityName == foreignKey.PkTable);

                    var foreignTable = entityViewModels.SingleOrDefault(x =>
                                                                        x.SchemaName == foreignKey.FkSchema && x.EntityName == foreignKey.FkTable);

                    var isOneToOne = false;
                    //Check one-2-one in case matched columns names and theirs orders
                    var originTableFullName  = $"{foreignKey.PkSchema}.{foreignKey.PkTable}";
                    var foreignTableFullName = $"{foreignKey.FkSchema}.{foreignKey.FkTable}";
                    if (pKeys.ContainsKey(originTableFullName) && pKeys.ContainsKey(foreignTableFullName))
                    {
                        var pKeyOrigin  = pKeys[originTableFullName];
                        var pKeyForeign = pKeys[foreignTableFullName];
                        if (foreignKey.PkColumns.Count == foreignKey.FkColumns.Count && foreignKey.PkColumns.Count == pKeyOrigin.Count && foreignKey.PkColumns.Count == pKeyForeign.Count)
                        {
                            isOneToOne = true;
                            for (var i = 0; i < pKeyOrigin.Count; i++)
                            {
                                if (pKeyOrigin[i] == foreignKey.PkColumns[i] && pKeyForeign[i] == foreignKey.FkColumns[i])
                                {
                                    continue;
                                }
                                isOneToOne = false;
                                break;
                            }
                        }
                    }

                    if (originTable != null && foreignTable != null)
                    {
                        var propertyName        = string.Empty;
                        var inversePropertyName = string.Empty;

                        var fkPreset    = fksPresetList.FirstOrDefault(x => x.ForeignKeyName == foreignKey.FkName && x.FkPropertyNames != null);
                        var hasFKPreset = fkPreset != null && fkPreset.FkPropertyNames != null;

                        if (hasFKPreset)
                        {
                            propertyName        = fkPreset.FkPropertyNames.PropertyName;
                            inversePropertyName = fkPreset.FkPropertyNames.InversePropertyName;
                        }

                        if (string.IsNullOrEmpty(propertyName))
                        {
                            foreach (var fkColumn in foreignKey.FkColumns)
                            {
                                propertyName = RemoveIdRegex.Replace(fkColumn, m => m.Groups["content"].Value).TrimEnd('_');
                            }

                            if (_options.ForeignPropertyRegex != null)
                            {
                                propertyName = Regex.Match(foreignKey.FkName, _options.ForeignPropertyRegex, RegexOptions.Singleline).Groups["PropertyName"].Value;
                                propertyName = propertyName.Replace("_", string.Empty);
                                if (propertyName.EndsWith("Id") || propertyName.EndsWith("ID"))
                                {
                                    propertyName = propertyName.Substring(0, propertyName.Length - 2);
                                }
                            }
                        }

                        if (fkPropertyDisplayNamesSettingsList != null && fkPropertyDisplayNamesSettingsList.Count > 0 && !hasFKPreset)
                        {
                            var fkPropertyDisplayNameSetting = fkPropertyDisplayNamesSettingsList.Find(x => x.Name == propertyName);
                            if (fkPropertyDisplayNameSetting != null && !string.IsNullOrEmpty(fkPropertyDisplayNameSetting.DisplayName))
                            {
                                propertyName        = fkPropertyDisplayNameSetting.DisplayName;
                                inversePropertyName = propertyName.ReplaceFirstOccurrance(originTable.EntityName, foreignTable.EntityName, true);
                            }
                        }

                        propertyName = PropertyHelper.GetColumnNameToDisplay(propertyName, originTable.EntityName, tablesColumnsSettingsList);

                        if (string.IsNullOrEmpty(inversePropertyName))
                        {
                            inversePropertyName = propertyName.ReplaceFirstOccurrance(originTable.EntityName, foreignTable.EntityName);
                        }

                        if (!isOneToOne)
                        {
                            if (!hasFKPreset || !string.Equals(fkPreset.FkPropertyNames.InversePropertyName, inversePropertyName, StringComparison.OrdinalIgnoreCase))
                            {
                                inversePropertyName = StringHelper.Pluralize(inversePropertyName);
                            }
                        }

                        if (originTable == foreignTable)
                        {
                            inversePropertyName = "Inverse" + propertyName;
                        }

                        var keyCount        = originTable.InverseKeys.Count(x => x.PropertyName == inversePropertyName);
                        var propName        = keyCount == 0 ? propertyName : $"{propertyName}_{keyCount}";
                        var inversePropName = keyCount == 0 ? inversePropertyName : $"{inversePropertyName}_{keyCount}";

                        var foreignKeyViewModel = foreignKey.CloneCopy <FkDefinition, ForeignKeyViewModel>();
                        foreignKeyViewModel.IsOptional          = foreignTable.Columns.Where(c => foreignKey.FkColumns.Contains(c.Name)).All(c => c.IsNullable);
                        foreignKeyViewModel.PropertyName        = propName;
                        foreignKeyViewModel.InversePropertyName = inversePropName;
                        foreignKeyViewModel.InverseEntityName   = originTable.EntityName;
                        foreignKeyViewModel.IsOneToOne          = isOneToOne;
                        foreignTable.ForeignKeys.Add(foreignKeyViewModel);

                        var inverseKeyViewModel = foreignKey.CloneCopy <FkDefinition, ForeignKeyViewModel>();
                        inverseKeyViewModel.PropertyName        = inversePropName;
                        inverseKeyViewModel.InversePropertyName = propName;
                        foreignKeyViewModel.InverseEntityName   = foreignTable.EntityName;
                        inverseKeyViewModel.IsOneToOne          = isOneToOne;
                        originTable.InverseKeys.Add(inverseKeyViewModel);
                    }
                }

                if (_options.AllowManyToMany)
                {
                    foreach (var model in entityViewModels)
                    {
                        var isManyToMany = model.Columns.Count == 2 && model.HasForeignKeys && model.Keys.Count == 2 && model.ForeignKeys.Count == 2;
                        if (isManyToMany && !_options.IgnoreObjectsForManyToMany.Contains($"[{model.SchemaName}].[{model.EntityName}]"))
                        {
                            var leftFk  = model.ForeignKeys.Single(f => f.FkColumns[0] == model.ColumnsEfPropertyOrder.First().Name);
                            var rightFk = model.ForeignKeys.Single(f => f.FkColumns[0] == model.ColumnsEfPropertyOrder.Last().Name);

                            var leftTable  = entityViewModels.SingleOrDefault(x => x.SchemaName == leftFk.PkSchema && x.EntityName == leftFk.PkTable);
                            var rightTable = entityViewModels.SingleOrDefault(x => x.SchemaName == rightFk.PkSchema && x.EntityName == rightFk.PkTable);

                            if (leftTable != null && rightTable != null)
                            {
                                model.IsManyToMany = true;

                                model.ManyToManyLeftTable  = leftTable.EntityName;
                                model.ManyToManyRightTable = rightTable.EntityName;

                                var leftTableInverseKey = leftTable.InverseKeys.SingleOrDefault(k => k.FkName == leftFk.FkName);
                                leftTableInverseKey.FkTable      = model.ManyToManyRightTable;
                                leftTableInverseKey.PropertyName = fksPresetList.Find(f => f.ForeignKeyName == leftTableInverseKey.FkName)?.FkPropertyNames.PropertyName ?? StringHelper.Pluralize(leftTableInverseKey.FkTable);
                                leftTableInverseKey.IsManyToMany = true;

                                var rightTableInverseKey = rightTable.InverseKeys.SingleOrDefault(k => k.FkName == rightFk.FkName);
                                rightTableInverseKey.FkTable      = model.ManyToManyLeftTable;
                                rightTableInverseKey.PropertyName = fksPresetList.Find(f => f.ForeignKeyName == rightTableInverseKey.FkName)?.FkPropertyNames.PropertyName ?? StringHelper.Pluralize(rightTableInverseKey.FkTable);
                                rightTableInverseKey.IsManyToMany = true;

                                model.ManyToManyLeftInversePropertyName  = leftTableInverseKey.PropertyName;
                                model.ManyToManyRightInversePropertyName = rightTableInverseKey.PropertyName;
                            }
                        }
                    }
                }

                var fileNames       = new List <string>();
                var modelsDirectory = Path.Combine(_options.Directory, _options.ModelsPath);
                Directory.CreateDirectory(modelsDirectory);

                foreach (var tableViewModel in entityViewModels.Where(e => !e.IsManyToMany))
                {
                    var setResult         = templateSet(tableViewModel);
                    var setResultFileName = Path.Combine(modelsDirectory, tableViewModel.EntityName + ".cs");
                    File.WriteAllText(setResultFileName, setResult);

                    fileNames.Add(setResultFileName);
                }

                if (_options.GenerateStoredProcedures)
                {
                    WriteObjectSets(spDefinitions, modelsDirectory, templateSet, fileNames, tablesColumnsSettingsList, entityPluralizeNameSettingsList);
                }

                if (_options.GenerateTableValuedFunctions)
                {
                    WriteObjectSets(tvfDefinitions, modelsDirectory, templateSet, fileNames, tablesColumnsSettingsList, entityPluralizeNameSettingsList);
                }

                var contextViewModel = new ContextViewModel
                {
                    ContextName          = _options.ContextName,
                    Namespace            = _options.Namespace,
                    Entities             = entityViewModels,
                    StoredProcedures     = spDefinitions,
                    TableValuedFunctions = tvfDefinitions
                };
                var contextResult         = templateContext(contextViewModel);
                var contextResultFileName = Path.Combine(modelsDirectory, contextViewModel.ContextName + ".cs");
                File.WriteAllText(contextResultFileName, contextResult);

                fileNames.Add(contextResultFileName);

                if (_options.CleanUp)
                {
                    var directoryFiles = Directory.GetFiles(modelsDirectory, "*.cs");

                    var filesToCleanUp = directoryFiles.Except(fileNames);

                    foreach (var s in filesToCleanUp)
                    {
                        File.Delete(s);
                    }
                }
            }
        }