C # DataSet из анализатора таблиц MySql с именем поля базы данных в свойстве - PullRequest
0 голосов
/ 28 сентября 2019

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

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

public class DatabaseHandler
{

    public DatabaseHandler()
    {

    }

    public DataSet Get<T>(string field = "id", string oper = ">", string input = "0") where T : BaseDataModel
    {
        DataSet ds = null;
        using (var conn = Connection())
        {
            string query = string.Format("SELECT * FROM {0} WHERE {1} {2} {3}", typeof(T).Name.ToLower(), field, oper, input);
            using (MySqlDataAdapter adapter = new MySqlDataAdapter(query, conn))
            {
                ds = new DataSet();
                adapter.Fill(ds);
            }
        }

        return ds;
    }

    private MySqlConnection Connection()
    {
        return new MySqlConnection("server=localhost;database=trainingsschema;uid=trainingsschema;pwd=password;");
    }

}

Тогда моя модель у меня в настоящее время:

public class Onderdeel : BaseDataModel
{
    public Onderdeel() : base() { }

    public virtual string Naam { get; set; }
}

База:

public class BaseDataModel
{
    public BaseDataModel()
    {

    }

    public virtual int Id { get; set; }

}

Так что, если я хочу проанализироватьрезультат этого набора данных в List<Onderdeel> Я должен был бы отобразить каждую таблицу, существующую вне этого DatabaseHandler.Get<T>() метода.Что бы я сделал, используя этот код:

myDataSet.Tables[0].AsEnumerable()
.Select(i => new ClassName() {
  i.MyProperty = dataRow.Field<String>("MyDatabaseFieldName")
}.ToList();

То, что я хочу заархивировать, - это простой картограф, в котором имена полей базы данных находятся в метаданных свойства.

Итак, моя модель станет примерно такой:

[FieldName("identifier")]
public virtual int Id { get; set; }

[FieldName("naam")]
public virtual string Name { get; set; }

И тогда я бы хотел заменить

i.MyProperty = dataRow.Field<String>("MyDatabaseFieldName")

на цикл, который будет проходить через все свойствамоей модели и сопоставить их с «FieldName», которое я прикрепил к нему, также DataType не будет проблемой, потому что он там есть.Наконец, DatabaseHandler.Get<T>() может затем вернуть List<T> вместо DataSet.

Кто может мне помочь?

1 Ответ

0 голосов
/ 28 сентября 2019

Через несколько часов никто не ответил здесь, поэтому мне пришлось провести некоторое расследование.Для тех, кто пытается это сделать:

  1. Добавьте новый класс с именем FieldName

    [AttributeUsage(AttributeTargets.Property)]
    public class FieldName : Attribute
    {
        public FieldName(string text)
        {
            this.Text = text;
        }
    
        public string Text { get; set; }
    }
    
  2. Убедитесь, что у вас есть базовая моделькак я и расширяйте любые модели баз данных этим, также добавьте атрибут FieldName к каждому отображаемому свойству

    public class BaseDataModel
    {
        public BaseDataModel()
        {
    
        }
    
        [FieldName("id")]
        public int Id { get; set; }
    
    }
    
  3. Добавьте этот помощник базы данных в свой проект (конечно, вы можете реализовать мойтакже код)

    public class DatabaseHandler
    {
    
    public DatabaseHandler()
    {
    
    }
    
    public List<T> Get<T>(string field = "id", string oper = ">", string input = "0") where T : BaseDataModel
    {
        List<T> list = new List<T>();
        DataSet ds = null;
        using (var conn = Connection())
        {
            string query = string.Format("SELECT * FROM {0} WHERE {1} {2} {3}", typeof(T).Name.ToLower(), field, oper, input);
            using (MySqlDataAdapter adapter = new MySqlDataAdapter(query, conn))
            {
                ds = new DataSet();
                adapter.Fill(ds);
            }
    
            foreach (DataRow row in ds.Tables[0].Rows)
            {
                object obj = Activator.CreateInstance(typeof(T));
    
                foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
                {
                    if (propertyInfo.CanWrite && propertyInfo.CanRead)
                    {
                        string fieldName = propertyInfo.CustomAttributes.ElementAt(0).ConstructorArguments[0].Value.ToString();
    
                        if (fieldName == null) continue;
    
                        propertyInfo.SetValue(obj, row.Field<dynamic>(fieldName));
                    }
                }
    
                list.Add(obj as T);
            }
        }
    
        return list;
    }
    
    private MySqlConnection Connection()
    {
        return new MySqlConnection("server=localhost;database=trainingsschema;uid=trainingsschema;pwd=password;");
    }
    
    }
    
  4. Это подключи и играй, у вас есть только 1 атрибут к вашим свойствам, если у вас есть больше, вы можете фильтровать по нужному пользовательскому атрибуту и ​​его значениям.

  5. Теперь вы можете позвонить любому List<T> из вашей базы данных следующим образом:

    List<Onderdeel> onderdelen = _db.Get<Onderdeel>();
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...