2011-12-21 3 views
1

В моей базе данных есть одна большая таблица «code» с системными кодами для значений, используемых во всей системе. Как так:Сопоставление таблицы кодов в BLToolkit

[TableName("code_entries")]       public class Code { 
    [MapField("code_nbr")][PrimaryKey, Identity] public int Id; 
    [MapField("code")]        public string Value; 
} 

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

[TableName("person")]        public class Person { 
     [MapField("person_nbr")][PrimaryKey, Identity] public int Id; 
     [MapField("dob")][Nullable]      public int BirthDate; 
     [MapField("eye_color")][Nullable]    public int EyeColorCode; 
     [MapField("hair_color")][Nullable]    public int HairColorCode;  
} 

Если EyeColorCode и HairColorCode выше карты до значений в таблице кодов, можно создать легкий способ отображения этих данных в рамках OR классов и получить весь объект в одном запросе?

Я хотел бы закончить с чем-то вроде:

// person.Id = 1 
// person.DOB = some date 
// person.EyeColor = "Blue" 
// person.HairColor = "Brown" 

ответ

1

Это не совсем то, что вы хотели, но вы можете использовать Associations

, чтобы вы могли добавить это к классу Person

[Association(ThisKey="eye_color", OtherKey="code_nbr", CanBeNull=true)] 
public Code EyeColor; 

[Association(ThisKey="hair_color", OtherKey="code_nbr", CanBeNull=true)] 
public Code HairColor; 

И затем сделать что-то вроде

from p in db.Person 
select new 
{ 
    Id  = p.Id, 
    DOB  = p.BirthDate, 
    EyeColor = p.EyeColor.Value, 
    HairColor = p.HairColor.Value 
}; 

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

+0

У нас есть некоторые такие коды, которые достаточно меняются, чтобы сделать это в данных. Это путь, к которому я направлялся, но проблема заключается в том, что он заставляет меня реагировать на все остальные столбцы также в новом объекте (Id и DOB в вашем примере) и мешает мне использовать сгенерированный класс базы данных (Person), не восстанавливая его. Эти значения кода используются во многих наших таблицах, поэтому я не смог бы использовать сгенерированные классы вообще. – Jason

1

Спасибо, Дэвид. Я пошел с вашим подходом, но немного изменил его, чтобы сделать его немного менее болезненным. Я добавил ассоциации к моим классам, как в вашем примере:

[Association(ThisKey = "EyeColorCode", OtherKey = "Id")] public Code EyeColor { get; set; } 
[Association(ThisKey = "HairColorCode", OtherKey = "Id")] public Code HairColor { get; set; } 

Затем я написал метод расширения. Он принимает новый объект и объединяет все записываемые свойства в исходный объект. Используя это, мне не нужно указывать все одно свойство в моем запросе, т.е .:

from p in db.Person 
select p.PropertyUnion(new Person() { 
{ 
    EyeColor = p.EyeColor, 
    HairColor = p.HairColor 
}; 

Это спасает меня совсем немного кода для некоторых из моих более сложных объектов, и я думаю, что это более читаемым. Вот код метода продления:

/// <summary> 
/// Union by retrieving all non-null properties from source parameter and setting those properties on the instance object 
/// </summary> 
public static T PropertyUnion<T>(this T destination, T source) { 
    // Don't copy from a null object 
    if (Object.ReferenceEquals(source, null) || Object.ReferenceEquals(destination, null)) { 
     return destination; 
    } 
    // copy properties 
    foreach (var property in source.GetType().GetProperties()) { 
     if (!property.CanWrite || !property.CanRead) 
      continue; 
     var match = destination.GetType().GetProperty(property.Name); 
     if (!match.CanWrite || !match.CanRead) 
      throw new MethodAccessException("Matching property '" + match.Name + "' must allow both read and write operations."); 
     var value = property.GetValue(source, null); 
     if (value != null && !value.Equals(Activator.CreateInstance(property.PropertyType))) 
      match.SetValue(destination, value, null); 
    } 
    return destination; 
} 

Еще раз спасибо за вашу помощь!

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