Автоматически создайте Перечисление на основе значений в справочной таблице базы данных?

В следующей строке

var str = document.getElementById('comment');

должно быть

document.getElementById('comment').value;

Вы также хотите добавить возвращаемое значение false, чтобы не допустить отправки формы без AJAX.

onclick = "submit();return false;"
107
задан DaveInCaz 30 July 2018 в 15:51
поделиться

9 ответов

Вы хотите Систему. Сеть. Компиляция. BuildProvider

Я также сомневаюсь относительно мудрости выполнения этого, но затем там, возможно, хороший вариант использования, о котором я не могу думать.

Что Вы ищете, Поставщики Сборки т.е. Система. Сеть. Компиляция. BuildProvider

Они используются очень эффективно SubSonic, можно загрузить источник и видеть, как они используют их, Вам не будет нужно ничто вдвое менее сложное, чем, что они делают.

Надеюсь, это поможет.

2
ответ дан Binary Worrier 24 November 2019 в 03:40
поделиться

Скажем, у Вас есть следующее в Вашем DB:

table enums
-----------------
| id | name     |
-----------------
| 0  | MyEnum   |
| 1  | YourEnum |
-----------------

table enum_values
----------------------------------
| id | enums_id | value | key    |
----------------------------------
| 0  | 0        | 0     | Apple  |
| 1  | 0        | 1     | Banana |
| 2  | 0        | 2     | Pear   |
| 3  | 0        | 3     | Cherry |
| 4  | 1        | 0     | Red    |
| 5  | 1        | 1     | Green  |
| 6  | 1        | 2     | Yellow |
----------------------------------

Создайте выбор для получения значений, в которых Вы нуждаетесь:

select * from enums e inner join enum_values ev on ev.enums_id=e.id where e.id=0

Создайте исходный код для перечисления, и Вы получите что-то как:

String enumSourceCode = "enum " + enumName + "{" + enumKey1 + "=" enumValue1 + "," + enumKey2 + ... + "}";

(очевидно, это создается в цикле некоторого вида.)

Затем прибывает забавная часть, Компилируя Ваше перечисление и с помощью него:

CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters cs = new CompilerParameters();
cp.GenerateInMemory = True;

CompilerResult result = provider.CompileAssemblyFromSource(cp, enumSourceCode);

Type enumType = result.CompiledAssembly.GetType(enumName);

Теперь Вам скомпилировали тип и готовый к употреблению.
Чтобы сохранить перечисление значений в DB, можно использовать:

[Enum].Parse(enumType, value);

где значение может быть любой целочисленным значением (0, 1, и т.д.) или перечислимый текст/ключ (Apple, Банан, и т.д.)

11
ответ дан Sani Singh Huttunen 24 November 2019 в 03:40
поделиться

Это должно быть фактическое перечисление? Как насчет того, чтобы использовать a Dictionary<string,int> вместо этого?

например,

Dictionary<string, int> MyEnum = new Dictionary(){{"One", 1}, {"Two", 2}};
Console.WriteLine(MyEnum["One"]);
15
ответ дан Autodidact 24 November 2019 в 03:40
поделиться

Перечисления должны быть указаны во время компиляции, Вы не можете динамично добавить перечисления во время времени выполнения - и почему был бы Вы, не будет никакого использования/ссылки им в коде?

С профессионального 2008 C#:

Действительная мощность перечислений в C# состоит в том, что негласно они инстанцируют как структуры, полученные из базового класса, Системы. Перечисление. Это означает, что возможно назвать методы против них для выполнения некоторых полезных задач. Обратите внимание, что из-за пути Платформа.NET реализована нет никакой потери производительности, связанной с обработкой перечислений синтаксически как структуры. На практике, после того как Ваш код компилируется, перечисления будут существовать как типы примитивов, точно так же, как интервал и плавание.

Так, я не уверен, что можно использовать Перечисления путем, Вы хотите.

47
ответ дан DaveInCaz 24 November 2019 в 03:40
поделиться

I'm doing this exact thing, but you need to do some kind of code generation for this to work.

In my solution, I added a project "EnumeratedTypes". This is a console application which gets all of the values from the database and constructs the enums from them. Then it saves all of the enums to an assembly.

The enum generation code is like this:

// Get the current application domain for the current thread
AppDomain currentDomain = AppDomain.CurrentDomain;

// Create a dynamic assembly in the current application domain,
// and allow it to be executed and saved to disk.
AssemblyName name = new AssemblyName("MyEnums");
AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(name,
                                      AssemblyBuilderAccess.RunAndSave);

// Define a dynamic module in "MyEnums" assembly.
// For a single-module assembly, the module has the same name as the assembly.
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name,
                                  name.Name + ".dll");

// Define a public enumeration with the name "MyEnum" and an underlying type of Integer.
EnumBuilder myEnum = moduleBuilder.DefineEnum("EnumeratedTypes.MyEnum",
                         TypeAttributes.Public, typeof(int));

// Get data from database
MyDataAdapter someAdapter = new MyDataAdapter();
MyDataSet.MyDataTable myData = myDataAdapter.GetMyData();

foreach (MyDataSet.MyDataRow row in myData.Rows)
{
    myEnum.DefineLiteral(row.Name, row.Key);
}

// Create the enum
myEnum.CreateType();

// Finally, save the assembly
assemblyBuilder.Save(name.Name + ".dll");

My other projects in the solution reference this generated assembly. As a result, I can then use the dynamic enums in code, complete with intellisense.

Then, I added a post-build event so that after this "EnumeratedTypes" project is built, it runs itself and generates the "MyEnums.dll" file.

By the way, it helps to change the build order of your project so that "EnumeratedTypes" is built first. Otherwise, once you start using your dynamically generated .dll, you won't be able to do a build if the .dll ever gets deleted. (Chicken and egg kind of problem -- your other projects in the solution need this .dll to build properly, and you can't create the .dll until you build your solution...)

I got most of the above code from this msdn article.

Hope this helps!

95
ответ дан 24 November 2019 в 03:40
поделиться

Просто показан ответ Pandincus с кодом «из полки» и некоторыми пояснениями: Для этого примера вам понадобятся два решения (я знаю, что это можно сделать и с помощью одного;), пусть продвинутые студенты представят это ...

Итак, вот DDL SQL для таблицы:

USE [ocms_dev]
    GO

CREATE TABLE [dbo].[Role](
    [RoleId] [int] IDENTITY(1,1) NOT NULL,
    [RoleName] [varchar](50) NULL
) ON [PRIMARY]

Итак, вот консоль программа, производящая dll:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.Data.Common;
using System.Data;
using System.Data.SqlClient;

namespace DynamicEnums
{
    class EnumCreator
    {
        // after running for first time rename this method to Main1
        static void Main ()
        {
            string strAssemblyName = "MyEnums";
            bool flagFileExists = System.IO.File.Exists (
                   AppDomain.CurrentDomain.SetupInformation.ApplicationBase + 
                   strAssemblyName + ".dll"
            );

            // Get the current application domain for the current thread
            AppDomain currentDomain = AppDomain.CurrentDomain;

            // Create a dynamic assembly in the current application domain,
            // and allow it to be executed and saved to disk.
            AssemblyName name = new AssemblyName ( strAssemblyName );
            AssemblyBuilder assemblyBuilder = 
                    currentDomain.DefineDynamicAssembly ( name,
                            AssemblyBuilderAccess.RunAndSave );

            // Define a dynamic module in "MyEnums" assembly.
            // For a single-module assembly, the module has the same name as
            // the assembly.
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule (
                    name.Name, name.Name + ".dll" );

            // Define a public enumeration with the name "MyEnum" and
            // an underlying type of Integer.
            EnumBuilder myEnum = moduleBuilder.DefineEnum (
                    "EnumeratedTypes.MyEnum",
                    TypeAttributes.Public,
                    typeof ( int )
            );

            #region GetTheDataFromTheDatabase
            DataTable tableData = new DataTable ( "enumSourceDataTable" );

            string connectionString = "Integrated Security=SSPI;Persist " +
                    "Security Info=False;Initial Catalog=ocms_dev;Data " +
                    "Source=ysg";

            using (SqlConnection connection = 
                    new SqlConnection ( connectionString ))
            {

                SqlCommand command = connection.CreateCommand ();
                command.CommandText = string.Format ( "SELECT [RoleId], " + 
                        "[RoleName] FROM [ocms_dev].[dbo].[Role]" );

                Console.WriteLine ( "command.CommandText is " + 
                        command.CommandText );

                connection.Open ();
                tableData.Load ( command.ExecuteReader ( 
                        CommandBehavior.CloseConnection
                ) );
            } //eof using

            foreach (DataRow dr in tableData.Rows)
            {
                myEnum.DefineLiteral ( dr[1].ToString (),
                        Convert.ToInt32 ( dr[0].ToString () ) );
            }
            #endregion GetTheDataFromTheDatabase

            // Create the enum
            myEnum.CreateType ();

            // Finally, save the assembly
            assemblyBuilder.Save ( name.Name + ".dll" );
        } //eof Main 
    } //eof Program
} //eof namespace 

Вот программа консоли, печатающая вывод (помните, что она должна ссылаться на dll). Пусть продвинутые студенты представят решение для объединения всего в одном решении с динамической загрузкой и проверкой, есть ли уже build dll.

// add the reference to the newly generated dll
use MyEnums ; 

class Program
{
    static void Main ()
    {
        Array values = Enum.GetValues ( typeof ( EnumeratedTypes.MyEnum ) );

        foreach (EnumeratedTypes.MyEnum val in values)
        {
            Console.WriteLine ( String.Format ( "{0}: {1}",
                    Enum.GetName ( typeof ( EnumeratedTypes.MyEnum ), val ),
                    val ) );
        }

        Console.WriteLine ( "Hit enter to exit " );
        Console.ReadLine ();
    } //eof Main 
} //eof Program
10
ответ дан 24 November 2019 в 03:40
поделиться

Вы можете использовать CodeSmith для создания чего-то вроде этого:

http://www.csharping.com/PermaLink,guid,cef1b637-7d37-4691-8e49-138cbf1d51e9.aspx

0
ответ дан 24 November 2019 в 03:40
поделиться

Я не думаю, что есть хороший способ делать то, что ты хочешь. И если вы подумаете об этом, я не думаю, что это то, что вам действительно нужно.

Если у вас есть динамическое перечисление, это также означает, что вы должны кормить его динамическим значением, когда вы на него ссылаетесь. Может быть, с помощью магии вы сможете создать своего рода IntelliSense , который позаботится об этом и сгенерирует для вас перечисление в файле DLL. Но примите во внимание объем работы, который потребуется, насколько неэффективным будет доступ к базе данных для получения информации IntelliSense, а также кошмар контроля версий сгенерированного файла DLL.

Если вы действительно не хотите вручную добавлять Значения перечисления (вам все равно придется добавить их в базу данных) вместо этого используйте инструмент генерации кода, например шаблоны T4 .

0
ответ дан 24 November 2019 в 03:40
поделиться

Использование динамических перечислений - это плохо, в любом случае. Вам придется столкнуться с проблемой «дублирования» данных, чтобы обеспечить ясный и простой код, который легко поддерживать в будущем.

Если вы начнете внедрять автоматически сгенерированные библиотеки, вы наверняка создадите еще больше путаницы для будущих разработчиков, которые должны обновите свой код, а не просто закодируйте enum в соответствующем объекте класса.

Другие приведенные примеры звучат красиво и захватывающе, но подумайте о накладных расходах на сопровождение кода по сравнению с тем, что вы получите от этого. Кроме того, будут ли эти значения меняться так часто?

0
ответ дан 24 November 2019 в 03:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: