在 BLToolkit 中映射代码表

发布于 2024-12-22 09:47:19 字数 1040 浏览 0 评论 0原文

在我的数据库中,有一个大型“代码”表,其中包含系统代码查找整个系统使用的值。像这样:

[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"

In my database, there is one large "code" table with system code look-ups for values used all over the system. Like so:

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

I am new to BLToolkit, and am hoping that there is a concept similar to the static Mappings I have seen, but that will allow me to easily map occurrences of these codes in other tables to their respective values. For instance:

    [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;    
}

If EyeColorCode and HairColorCode above map to values in the Codes table, can I create an easy way to map that data within the OR classes and obtain the whole object in a single query?

I'd like to end up with something like:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浮萍、无处依 2024-12-29 09:47:19

谢谢大卫。我采用了你的方法,但稍微修改了一下,以减轻我的痛苦。我在我的类中添加了关联,如您的示例所示:

[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;
}

再次感谢您的帮助!

Thanks David. I went with your approach, but modified it slightly to make it a little less painful form me. I added associations to my classes as in your example:

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

Then I wrote an extension method. It takes a new object, and merges all the writable properties into the source object. Using this, I don't need to specify every single property in my query, i.e.:

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

This saves me quite a bit of code for some of my more complex objects, and I think it is more readable. Here is the code for the extension method:

/// <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;
}

Thanks again for your help!

夏了南城 2024-12-29 09:47:19

这并不是您真正想要的,但您可以使用 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,那么我只需
刷新集合

It's not really what you wanted but you could use Associations

so you could add this to your Person class

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

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

And then do something like

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

Anyway these seem like the type of codes that almost never change
I usually put these on the client at startup and then fill in the description when I display the data, makes everything a lot easier, and if I can't find an Id then I just
refresh the collection

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文