BebeSaiyan Ответов: 2

Как использовать атрибут и отражение для извлечения данных из базы данных SQL с помощью ASP.NET?


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

Что я уже пробовал:

Первоначально у меня был класс, который устанавливал бы данные из SQL с такими свойствами:

public class TShirt
{   
public int Id { get; set; }
public string Type { get; set; }
public string Brand { get; set; }

public TShirt()
{

}
public TShirt(int id, string type, string brand)
{
    Id = id;
    Type = type;
    Brand = brand;
}


И я бы подключился к базе данных через этот код:

public static ArrayList GetTShirt(string itemCategory)
{
ArrayList list = new ArrayList();
string query = string.Format("SELECT * FROM shirt WHERE brand LIKE @brand");

try
{
    conn1.Open();
    command1.CommandText = query;
    command1.Parameters.Add(new SqlParameter("brand", itemCategory));
    SqlDataReader reader = command1.ExecuteReader();

    while (reader.Read())
    {
        int id = reader.GetInt32(0);
        string type = reader.GetString(1);
        string brand = reader.GetString(2);

        TShirt t = new TShirt(id, type, brand);
        list.Add(t);
    }
}
finally
{
    conn1.Close();
    command1.Parameters.Clear();
}

return list;
}


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

2 Ответов

Рейтинг:
0

Richard Deeming

Звучит так, как будто вы ищете Щеголеватый[^].

public static IList<TShirt> GetTShirt(string itemCategory)
{
    using (var con = new SqlConnection("..."))
    {
        return con.Query<TShirt>("SELECT * FROM shirt WHERE brand LIKE @brand", new { brand = itemCategory }).ToList();
    }
}

Записи:
Не храните соединение как поле уровня класса. Создайте его, когда это необходимо, и заверните в using блок. Возможно, вы захотите поместить создание в отдельный метод и сохранить строку подключения в конфигурационном файле.

Не используйте ArrayList класс. Вместо этого используйте общую коллекцию.
Универсальные коллекции в интернет .Чистая рамки[^]

SELECT * FROM ... это вообще плохая идея. Вы должны явно указать имена столбцов, которые хотите загрузить.


BebeSaiyan

@Richard Deeming-спасибо за решение,но я пошел по маршруту Entity Framework.

Рейтинг:
0

Jörgen Andersson

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

Но чтобы ответить на специфику вашего вопроса.
Первая часть состоит в том, чтобы получить свойства целевого класса:

Type TShirtType = typeof(TShirt);

А затем вы можете зациклить свойства с помощью:
foreach (PropertyInfo TShirtMember in TShirtType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
    if (TShirtMember.CanWrite)  // Well you can't map readonly properties

Затем вам нужно сравнить с полями в datareader.
Сделайте внутреннюю петлю для полей:
for (int Ordinal = 0; Ordinal < reader.FieldCount; Ordinal++)

Теперь вы можете сравнить имена:
TShirtMember.Name.ToLower() == reader.GetName(Ordinal).ToLower()

Если у вас есть совпадение вы можете установить это свойство:
TargetMember.SetValue(t,reader.Getvalue(Ordinal))
Где t ваш экземпляр футболки


Richard Deeming

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

И вы всегда должны нормализовать строки в верхний регистр для сравнения, чтобы избежать проблемы "турецкого i". Но было бы лучше использовать string.Equals(x, y, StringComparison.OrdinalIgnoreCase) для выполнения сравнения без учета регистра, так как это позволяет избежать создания копии входных строк.

Jörgen Andersson

Вы совершенно правы, это была быстрая запись, чтобы объяснить принцип.
Хорошая обратная связь по сравнению, Я никогда не сталкивался с турецкой проблемой.
Вопрос в том, как лучше всего справиться с этим в SQL? Верхний не намного лучше, так как есть пунктирный верхний регистр I, а также.
<edit & gt;отбросьте это, SQL server не чувствителен к регистру, используя параметры сортировки по умолчанию.< / edit>

BebeSaiyan

Спасибо за новое озарение. Обязательно попробую это сделать.