1

我有一个在我的自定义 DB ORM 工具中使用的 C# 类,称为 DbFieldAttribute。

我把它放在我的领域,像这样:

[DbField("User_Id")]
public int UserId{ get; set; }

挑战:从我的属性构造函数代码中,获取与属性关联的字段的 FieldInfo。在上述情况下,它将为我提供 UserId 的 FieldInfo。

任何帮助都会很棒。谢谢。

4

2 回答 2

0

不幸的是,据我所知,没有办法完成您的要求。

但是,如果您没有必要在构造函数中获取PropertyInfoFieldInfo对象,而是对将其传递给方法感到满意,那么有一个可能的解决方案。

首先,您的DbField类需要按以下方式定义。

class DbField : Attribute
{
    public DbField(string source) { }

    public void GetInstance(PropertyInfo source)
    {
        Console.WriteLine(source.Name);
    }
}

然后,您需要定义以下类,该类将获取所有(在本例中)标有DbField属性的属性,并将它们传递给GetInstance(PropertyInfo)方法。

class ActivateAttributes
{
    public ActivateAttributes(object source)
    {
        source.GetType()
              .GetProperties()
              .Where(x => x.GetCustomAttributes().OfType<DbField>().Any())
              .ToList()
              .ForEach(x => (x.GetCustomAttributes().OfType<DbField>().First() as DbField).GetInstance(x));
    }
}

您触发此过程的方式是在一个抽象类中,它是这样定义的。

abstract class AbstractDecoratedClass
{
    public AbstractDecoratedClass()
    {
        new ActivateAttributes(this);
    }
}

现在,您的目标类(其属性由DbField属性修饰)只需要从该类派生,这样您就不会被构造函数内部的调用所困扰。

class DecoratedClass : AbstractDecoratedClass
{
    [DbField("User_Id")]
    public int UserId { get; set; }

    [DbField("User_Id2")]
    public int UserId2 { get; set; } 
}

您现在只剩下测试解决方案了,如此处所示。

class Program
{
    static void Main()
    {
        new DecoratedClass();

        Console.Read();
    }
}
于 2013-07-20T00:42:01.193 回答
0

正如@Mario 指出的那样,无法直接解决该解决方案,但这是我最终采用的解决方案。

关键是要知道仅属性无法知道此信息,但是在调用它时,可以合理地预期 FieldInfo 或 PropertyInfo 也可用。

我最初的问题是我的 ORM 代码查看属性以确定字段/属性是否与数据库字段相关。然后,我有一些实例,其中类中的 Prop/Field 名称与数据库不匹配,原因是使其更符合 Code/Db 的逻辑。在这些情况下,我需要传入一个要使用的字段名称而不是实际字段。我希望该属性可以做更多的工作,或者至少有助于使其对将来使用它的任何代码更加明显。

(我删除了与此解决方案无关的 xml 注释和额外代码)

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class DbFieldAttribute : Attribute
{
    private string fieldName = "";

    public DbFieldAttribute() { }

    public DbFieldAttribute(string fieldName)
    {
        this.fieldName = fieldName;
    }

    public string FieldName(PropertyInfo pi)
    {
        if (this.fieldName != "") return this.fieldName;
        else return pi.Name;
    }

    public string FieldName(FieldInfo fi)
    {
        if (this.fieldName != "") return this.fieldName;
        else return fi.Name;
    }

现在,当我的 ORM 代码需要字段名称时,它必须传入与该字段相关的字段或属性信息。这意味着所需要的现在在属性使用中是固有的,而不是需要在外部代码中派生。

于 2013-07-22T14:54:30.603 回答