我最近创建了通用sql命令生成代码。一切都有效,除了我目前正在努力的一件事。 如何通过给定的属性名称获取Answer prop的实例/值?
我有什么:
将问题实例作为对象(例如myObject)
问题的属性+内部道具名称(字符串)+内部类型
[Table("Question")]
public class Question
{
[Column("QuestionID", true)]
public int QuestionId { get; set; }
[Column("Number")]
public string Nr { get; set; }
[Column("CorrectAnswer", typeof(Answer), nameof(Answer.Text))]
public Answer CorrectAnswer { get; set; }
}
[AttributeUsage(AttributeTargets.Property, Inherited = false)]
public class ColumnAttribute : DatabaseAttribute
{
public bool IsTechnicalId { get; private set; } = false;
public string DeepPropName { get; private set; } = null;
public Type DeepClass { get; private set; } = null;
public bool HasDeepProp { get; private set; } = false;
public ColumnAttribute(string name) : base(name)
{
}
/// <summary>
/// Creates a deep object property column definition
/// </summary>
/// <param name="name"></param>
/// <param name="deepProperty"></param>
public ColumnAttribute(string name, Type deepClass, string deepPropertyName) : base(name)
{
DeepPropName = deepPropertyName;
DeepClass = deepClass;
HasDeepProp = true;
}
public ColumnAttribute(string name, bool isTechnicalId) : this(name)
{
IsTechnicalId = isTechnicalId;
}
}
我获取道具和值的当前代码如下所示。
public static IEnumerable<DatabaseAttributeContainer> GetAllAttributes<TClass>(TClass obj, bool inherit = false)
{
List<DatabaseAttributeContainer> propValues = new List<DatabaseAttributeContainer>();
object value = null;
Type classType = typeof(TClass);
PropertyInfo[] pInfos = inherit ? classType.GetProperties() : classType.GetProperties(_NonInheritedFlag);
DatabaseAttribute[] attributes = null;
DatabaseAttribute attr = null;
ColumnAttribute colAttr = null;
PropertyInfo[] pInfosDeep = null;
foreach (PropertyInfo pInfo in pInfos)
{
attributes = (DatabaseAttribute[])pInfo.GetCustomAttributes(typeof(DatabaseAttribute));
attr = attributes.FirstOrDefault();
if(!(attr is IgnoreAttribute))
{
colAttr = (ColumnAttribute)attr;
//broken
if(colAttr.HasDeepProp)
{
pInfosDeep = colAttr.DeepClass.GetProperties(_NonInheritedFlag);
foreach (PropertyInfo pInfoDeep in pInfosDeep)
{
if(pInfoDeep.Name == colAttr.DeepPropName)
{
//Need object instance of Answer for "GetValue()"
//value = pInfoDeep.GetValue(obj, null);
break;
}
}
}
//broken end
else
{
if (obj != null)
value = pInfo.GetValue(obj, null);
propValues.Add(new DatabaseAttributeContainer(attr, value));
}
}
}
propValues.Add(GetAttributeByClass<TClass>());
if (propValues.Count == 0)
throw new ApplicationException(typeof(TClass) + "has no DatabaseAttribute attribute");
return propValues;
}
除了唯一的例外,一切都完美无缺:如何在搜索对象中获取另一个对象的属性值? 我能够获取实例化对象的任何属性实例吗?
EDIT1:
我可以得到裁判if(pInfo.Name == "CorrectAnswer")
answerRef = pInfo.GetValue(obj, null);
然后从answerRef castet获取道具来回答获得价值 对于我给定的propName
答案 0 :(得分:0)
解决方案
public static IEnumerable<DatabaseAttributeContainer> GetAllAttributes<TClass>(TClass obj, bool inherit = false)
{
List<DatabaseAttributeContainer> propValues = new List<DatabaseAttributeContainer>();
object value = null;
Type classType = typeof(TClass);
PropertyInfo[] pInfos = inherit ? classType.GetProperties() : classType.GetProperties(_NonInheritedFlag);
DatabaseAttribute[] attributes = null;
DatabaseAttribute attr = null;
ColumnAttribute colAttr = null;
PropertyInfo pInfoDeep = null;
object deepRef = null;
//ToDo: get custom attributes from this obj and iterate over it with prop name
//get propInfo (performance increase)
foreach (PropertyInfo pInfo in pInfos)
{
attributes = (DatabaseAttribute[])pInfo.GetCustomAttributes(typeof(DatabaseAttribute));
attr = attributes.FirstOrDefault();
if (!(attr is IgnoreAttribute))
{
colAttr = attr as ColumnAttribute;
if (colAttr != null && colAttr.HasDeepProp && obj != null)
{
//get ref value
deepRef = pInfo.GetValue(obj, null);
deepRef = Convert.ChangeType(deepRef, colAttr.DeepType);
pInfoDeep = deepRef.GetType().GetProperty(colAttr.DeepPropName);
if (pInfoDeep == null)
throw new ApplicationException("Property with name " + colAttr.DeepPropName + " not found");
value = pInfoDeep.GetValue(deepRef, null);
}
else
{
if (obj != null)
value = pInfo.GetValue(obj, null);
}
propValues.Add(new DatabaseAttributeContainer(attr, value));
}
}
propValues.Add(GetAttributeByClass<TClass>());
if (propValues.Count == 0)
throw new ApplicationException(typeof(TClass) + "has no DatabaseAttribute attribute");
return propValues;
}