3

我想关闭UpdateCheck所有成员的功能(除了他们的主键)。现在我按照下面的示例作为指导,但是表的 MetaDataMembers 仍然设置为Always.

http://www.the-lazy-coder.com/2013/04/set-updatecheck-to-never.html

上面的代码片段只是让您更改属性,但它似乎永远不会被拾取,因为我可以在代码运行时调试代码并且我看到所有属性都被设置,所以我假设属性更改不会更改底层对象。

现在,如果我要改变方法并直接从 RowType 获取 MetaDataMembers,我会注意到它们具有该UpdateCheck属性,但只有一个 getter。那么有没有办法(如果需要,通过反射)在设置后覆盖这个属性?即使查看了反编译的源代码,它也是一个抽象类,我找不到任何可用于参考的实现。

我正在使用 SQLMetal 生成上下文文件,因此没有可用的设计器修补程序,虽然有些人会说我应该运行一些文本编辑宏来解析和更改属性,但当我应该只是时,这一切听起来都太啰嗦了能够进入内存中的对象并告诉它忽略以前告诉过的任何内容。

所以!有没有办法覆盖实体中的属性?我已经尝试在两个构造函数中运行该链接中的原始代码,在创建对象之后并且就在我即将进行更新之前,但是没有任何更改似乎坚持或至少传播到重要的地方,并且几乎没有任何有关如何以编程方式执行此操作的材料。

4

1 回答 1

4

在互联网上搜索后,我发现没有很好的方法,虽然有我最初提到的链接,但它不起作用,因为它适用于部分正确的属性,但在上述情况下,它们正在处理的属性不在内存中,只是装饰品,无论如何下面的代码似乎可以工作但并不好:

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。它是非常防御性地编写的,因为这种方式会拉回许多没有所有所需数据的成员,因此它必须将它们过滤掉并且只处理那些有的成员。

于 2013-06-14T14:51:10.157 回答