我想关闭所有成员的UpdateCheck
功能(除了它们的主键)。现在我按照下面的例子作为指导,但是我的表的metadatmembers仍然设置为Always
。
上面的代码片段只是让你改变属性,但是它似乎永远不会被捡起来,因为我可以调试代码时,它正在运行,我看到所有的属性被设置,所以我假设属性的改变不会改变底层对象。
现在,如果我要改变方法,只是直接从RowType我注意到他们有UpdateCheck
属性,但只有一个getter。那么,是否有一种方法(通过反射,如果需要)覆盖此属性一旦设置?即使在查看反编译的源代码后,它也是一个抽象类,我找不到任何可参考的实现。
我使用SQLMetal来生成上下文文件,因此没有设计器可用的修改,尽管有些人会说我应该运行一些文本编辑宏来解析和更改属性,但是当我应该仅仅能够进入内存中的对象并告诉它忽略之前告诉它的任何内容时,这听起来太冗长了。
如此!是否有一种方法可以覆盖实体中的属性?我已经尝试在两个构造函数中运行该链接中的原始代码,在创建对象之后,就在我即将进行更新之前,但是似乎没有任何更改可以坚持或至少传播到重要的地方,并且几乎没有任何关于如何以编程方式执行此操作的材料。
在互联网上搜索后,我发现没有很好的方法来做到这一点,虽然有我最初提到的链接,但它不起作用,因为它对部分正确的属性起作用,但在上面的情况下,它们正在处理不在内存中的属性,只是装饰,无论如何,下面的代码似乎可以工作,但不太好:
public static void SetUpdateCheckStatus(this IDataContext dataContext, UpdateCheck updateCheckStatus)
{
var tables = dataContext.Mapping.GetTables();
foreach (var table in tables)
{
var dataMembers = table.RowType.DataMembers;
foreach (var dataMember in dataMembers)
{
if (!dataMember.IsPrimaryKey)
{
var dataMemberType = dataMember.GetType();
if (dataMemberType.Name == "AttributedMetaDataMember")
{
var underlyingAttributeField = dataMember.GetType().GetField("attrColumn", BindingFlags.Instance | BindingFlags.NonPublic);
if (underlyingAttributeField != null)
{
var underlyingAttribute = underlyingAttributeField.GetValue(dataMember) as ColumnAttribute;
if (underlyingAttribute != null)
{ underlyingAttribute.UpdateCheck = updateCheckStatus; }
}
}
else
{
var underlyingField = dataMember.Type.GetField("updateCheck", BindingFlags.Instance | BindingFlags.NonPublic);
if (underlyingField != null)
{ underlyingField.SetValue(dataMember, updateCheckStatus); }
}
}
}
}
}
IDataContext只是一个包装器,我们放在DataContext周围用于模拟目的,所以可以随意将其更改为DataContext。它的编写非常具有防御性,因为这样会拉回许多没有所有所需数据的成员,因此它必须将它们过滤出来,只处理那些具有所需数据的成员。