在我的数据库中,有一个大的“代码”表,其中包含系统代码查找,用于在整个系统中使用的值。像这样:
[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映射到Codes表中的值,我是否可以创建一种简单的方法来在OR类中映射该数据并在单个查询中获取整个对象?
我想最终得到类似的东西:
// person.Id = 1
// person.DOB = some date
// person.EyeColor = "Blue"
// person.HairColor = "Brown"
答案 0 :(得分: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,那么我只是 刷新集合
答案 1 :(得分: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;
}
再次感谢您的帮助!