Отражение альтернативы производительности - PullRequest
0 голосов
/ 05 апреля 2019

Я реализую Уровень доступа к данным для проекта, использующего обычный Dapper.Я использую как общий репозиторий для операций CRUD, так и универсальный построитель запросов для своих запросов.

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

Моя модель выглядит так: -

    [ModelAttributes(Key = "CubeID")]
    public class RepSysCube
    {
        public int CubeID { get; set; }
        public int ApplicationID { get; set; }
        public int AuthorisationID { get; set; }
        public string CubeName { get; set; }
        public string CubeDescription { get; set; }
        public byte[] Image { get; set; }
    }

ModelAttribute выглядит примерно так: -

    [AttributeUsage(AttributeTargets.Class)]
    internal class ModelAttributes : System.Attribute
    {
        private string _Key;
        public string Key
        {
            get
            {
                return _Key;
            }
            set
            {
                _Key = value;
            }
        }
    }

Мой репозиторий выглядит примерно так: -

public class Repository<T> : IRepository<T> where T : class
{
    public T GetById(int id)
    {
        string query = queryBuilder.SelectByID(id);
        var queryResult = dbConnection.Query<T>(query);
        return queryResult.FirstOrDefault();
    }
}

Теперь для генерации своих запросов я могу использовать что-то вроде этого: -

internal class QueryBuilder<T> : IQueryBuilder<T> where T : class
{
    string _Query = string.Empty;
    public string SelectByID(int ID)
    {
        _Query = string.Format("SELECT * FROM {0} WHERE {1} = '{2}'", typeof(T).Name, ((ModelAttributes)typeof(T).GetCustomAttributes(false).Where(x => x == (ModelAttributes)x).First()).Key, ID);
        return _Query;
    }
}

Моя проблема заключается в использовании

((ModelAttributes)typeof(T).GetCustomAttributes(false).Where(x => x == (ModelAttributes)x).First()).Key

Я знаю, что Reflection в C # имеет затраты на производительность.Есть ли какой-нибудь другой способ, где я могу достичь чего-то похожего на это, где я могу легко определить характеристики класса Model.

Я пытался использовать функцию внутри класса Model, но к моему ужасу, я не могвызвать функцию с помощью T.

1 Ответ

0 голосов
/ 05 апреля 2019

Поскольку общие статические переменные отличаются по типу, т. Е. QueryBuilder<Car>.KeyField - это переменная, отличная от QueryBuilder<Truck>.KeyField, вы можете выполнить отражение только один раз и просто использовать значение переменной для последующих вызовов, исключая затраты (значительные или нет) на вызовотражение при каждом вызове метода.

internal class QueryBuilder<T> : IQueryBuilder<T> where T : class
{
    private static readonly string KeyField = ((ModelAttributes)typeof(T).GetCustomAttributes(false).Where(x => x == (ModelAttributes)x).First()).Key;
    private string _Query = string.Empty;
    public string SelectByID(int ID)
    {
        // don't create your query this way.  use a parameterized query
        _Query = string.Format("SELECT * FROM {0} WHERE {1} = '{2}'", typeof(T).Name, KeyField, ID);
        return _Query;
    }
}
...