2010-08-17 2 views
6

Это приложение winforms C#.Как сохранить ссылку на свойство объекта в другом объекте?

Предисловие:

Я создаю форму, которая позволит пользователям импортировать данные из существующей базы данных MySql или SQL Server в моей базе данных SQL Server. Это позволяет пользователям быстро импортировать IP-адреса и другие данные без повторного ввода его через элемент управления.

Пример:

упрощенный, у меня есть два объекта, FieldObject и SensorObject. FieldObject существует для хранения имен и типов полей исходной и целевой базы данных. SensorObject - это объект, который я позже заполняю из записей в базе данных. Для простоты я опускаю обработку типов и другие функции, которые не имеют отношения к вопросу. (Данные для DestinationField ограничивается список, который я предоставить пользователю, и приходит из массива или списка в программе.) Вот пример как:

public class FieldObject 
{ 
    public string DestinationField {get; set;} 
    public string SourceField {get; set;} 
} 

public class SensorObject 
{ 
    public string Name {get; set;} 
    public string IPAddress {get; set;} 
} 

Проблема:

Когда пользователь заполняет различные поля FieldObject, я использую эту информацию для заполнения базы данных назначения, хотя у меня есть большой оператор switch, который проверяет имя поля назначения, чтобы узнать, какое свойство принадлежит SensorObject.

Например:

// Reader is a SqlDataReader with the prerequisite database connection 
FieldObject myField = new FieldObject 
    { 
     DestinationField = "name", 
     SourceField = "proprietary" 
    }; 
SensorObject mySensor = new SensorObject(); 
switch (myField.DestinationField) 
{ 
    case "name": 
     mySensor.Name = Convert.ToString(Reader[myField.DestinationField]); 
     break; 
    case "ip_address": 
     mySensor.IPAddress = Convert.ToString(Reader[myField.DestinationField]); 
     break; 
} 

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

Вопрос:

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

Что-то вроде:

foreach(FieldObject f in myFieldList) 
{ 
    mySensor(f.mySensorField) = Convert.ToString(Reader[f.DestinationField]); 
} 

Я не уверен, что метод в C# одалживает к такого рода приложения. Я изучил ссылочные ценности и размышления, и они не кажутся подходящими.

Я ценю любые идеи и советы или даже способы переосмыслить этот подход.

+0

Можете ли вы использовать ORM для решения этой проблемы, поэтому вам не нужно писать этот избыточный код? –

+0

Реляционное сопоставление объектов? Я подозреваю, что мне не пришлось искать, что такое «ОРМ», я мог бы использовать его. :) Извините, все-таки новичок в большинстве случаев! – JYelton

+0

Посмотрите на NHibernate: http://nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx в долгосрочной перспективе ORM убирают большую часть боли при работе с реляционными базами данных, однако они требуют некоторой работы для начала. – Zebi

ответ

2

Для этого необходимо использовать отражение. Если в конечном итоге, как что-то вроде:

var sensorFields = typeof(SensorObject).GetProperties() 
foreach(var field in fields) 
{ 
    var info = sensorFields.First(sensorField => sensorField.Name == field.Name); 
    var value = Convert.ToString(Reader[field.Destination]); 
    info.SetValue(sensorObj, value, new object[0]); 
} 

GetProperties получает информацию свойства для каждого свойства, которые могут быть использованы для установки значения.

Конечно, информация о свойствах может быть кеширована.Просто напишите его один раз и рефакторинг, как только он запустится. Не слишком усложняйте слишком много, это называется преждевременной оптимизацией и ведет прямо в ад;)

+0

Это выглядит очень полезно, это помогает кому-то, кто понимает отражение и его использование, указывать правильное направление! – JYelton

+0

Если вы замените содержимое цикла на 'lookup.Add (field.Name, field)', где 'lookup' является' Dictionary ', это все, что вам нужно для кэширования этих результатов позже. –

+0

Я не понимаю, что такое 'Reader [myField.DestinationField]', но я не уверен, что вам нужно будет преобразовать его в строку. Или, если бы вы это сделали, я бы подумал, что вы просто вызываете 'x.ToString()' вместо того, чтобы использовать 'Convert.ToString (x)'. –

1

На самом деле, отражение - неплохая идея, особенно если вы заполняете словарь с помощью PropertyInfo экземпляров для каждого имени свойства.

1

Вы можете сделать это с отражением. Вы получаете PropertyInfo свойства с именем, о котором идет речь, получите MethodInfo установщика, а затем вызовите его.

Возможно, возможно сохранить ассоциативный массив (словарь или HastTable и т. Д.) Значений, хранящихся по имени, что было бы гораздо легче иметь дело, если это необходимо.

+1

Возможно, имеет смысл вызвать 'GetSetMethod' в' PropertyInfo', который возвращает 'MethodInfo 'самому устройству. –

+0

@Steven, вы правы. Я забыл, когда объект обновлялся, что в вопросе к тому времени, когда я начал отвечать :) Исправлено, спасибо. –

+1

Просто используйте PropertyInfo.SetValue (Object, Object, Object []) – Zebi

Смежные вопросы