我有一个在我的自定义 DB ORM 工具中使用的 C# 类,称为 DbFieldAttribute。
我把它放在我的领域,像这样:
[DbField("User_Id")]
public int UserId{ get; set; }
挑战:从我的属性构造函数代码中,获取与属性关联的字段的 FieldInfo。在上述情况下,它将为我提供 UserId 的 FieldInfo。
任何帮助都会很棒。谢谢。
我有一个在我的自定义 DB ORM 工具中使用的 C# 类,称为 DbFieldAttribute。
我把它放在我的领域,像这样:
[DbField("User_Id")]
public int UserId{ get; set; }
挑战:从我的属性构造函数代码中,获取与属性关联的字段的 FieldInfo。在上述情况下,它将为我提供 UserId 的 FieldInfo。
任何帮助都会很棒。谢谢。
不幸的是,据我所知,没有办法完成您的要求。
但是,如果您没有必要在构造函数中获取PropertyInfo或FieldInfo对象,而是对将其传递给方法感到满意,那么有一个可能的解决方案。
首先,您的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();
}
}
正如@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 代码需要字段名称时,它必须传入与该字段相关的字段或属性信息。这意味着所需要的现在在属性使用中是固有的,而不是需要在外部代码中派生。