2

我设计了一个数据库,用 sqlmetal 生成了 c# 代码,一切正常。
现在,我正在开发一个 UI,我想为 sqlmetal 创建的类添加一些属性。
阅读此 SO Q&A 后:我可以在部分类中定义属性,然后用另一个部分类中的属性标记它们吗?这个atrticle:MSDN - MetadataTypeAttribute Class我尝试了以下内容:

[MetadataType(typeof(GUI.metadata.BooksMetaData))]
public partial class Book
{
    public void fun()
    {
        
    }
}

namespace GUI.metadata
{
    public class BooksMetaData
    {
        [DisplayName("hello")]
        public object Shelf { get; set; }
    }
}

我检查了 VS 是否重新调整Book了函数中的属性fun,但它没有,所以我并不惊讶该DisplayName属性没有改变。

我做错了什么以及如何解决?

(我使用的是 c#,VS 2010 pro,sqlmetal 生成的代码与 GUI 所在的 .dll 不同)

4

1 回答 1

2

请注意,在您提到的线程中,其中一条评论说:“这不是 OP 提出的问题的通用解决方案。属性的消费者仍然需要知道查找元数据类 - 即这些属性将不能由 Attribute.GetCustomAttribute(...) 返回。” 这意味着它不是添加属性的通用解决方案。这是一个解决方案,它要求读取属性的方法理解“MetadataType”,只需转到另一个类以获得其他属性。它不会自动发生。

我知道这不是一个完整的答案,但我建议使用 Mono.Cecil 进行某种后处理,例如:

// pseudo code!

// for every type in assembly...
foreach (var targetType in assembly.Types)
{
    // find type which adds attributes to original type
    var sourceTypeName = targetType.Name + "Attributes";
    var sourceType = assembly.Types.FirstOfDefault(t => t.Name = sourceTypeName);

    if (sourceType == null) continue; // no type adding attributes

    // for each property in this type...
    foreach (var targetProperty in targetType.Properties)
    {
        // find property which is supposed to have additional attributes
        var sourceProperty = sourceType.Properties.FirstOfDefault(
            p => p.Name = targetProperty.Name);
        if (sourceProperty == null) continue; // no such property

        // copy attributes
        foreach (var sourceAttribute in sourceProperty.Attributes)
        {
            targetProperty.Attributes.Add(sourceAttribute);
        }
    }
}
于 2013-09-18T09:25:10.407 回答