2016-10-05 6 views
3

私の状況は次のとおりです。 Entity Frameworkでデータベースファーストアプローチを使用してMVC WebサイトをVisual Studio 2013でコーディングしています。EFでMVCの部分クラスのカスタム属性にアクセス

EFが自動的にモデルを生成します。しかし、私はカスタム属性を追加する必要があります(データ検証には必須ではなく、内部プロセスにも必須です)。リフレクションによって、これらのカスタム属性にアクセスします。

私は以下のアプローチを試みたのは、私が

public partial class Application { 
    public int AppID {get; set;} 
    public string Name {get; set;} 
    //etc... 
} 

を持っているとしましょう:私は部分クラスを継続し、別のファイルに

•を:

public partial class Application { 
    [MyAttributeOne] 
    public int AppID { get; set; } 

    [DataType(DataType.Text)] 
    [MyAttributeTwo] 
    public string Name { get; set; } 
} 

•メタデータクラスを使用します

public class ApplicationMetadata { 
    [MyAttributeOne] 
    public int SolutionID { get; set; } 

    [DataType(DataType.Text)] 
    [MyAttributeTwo] 
    public string Name { get; set; } 
} 

[MetadataType(typeof(ApplicationMetadata))] 
public partial class Application { } 
public class ApplicationMetadata { 
    [MyAttributeOne] 
    public int SolutionID { get; set; } 

    [DataType(DataType.Text)] 
    [MyAttributeTwo] 
    public string Name { get; set; } 
} 

public partial class Application : ApplicationMetadata { } 

•そして、私は基本的に前の2つのアプローチを行う代わりに、私は「アプリケーション」クラス内の属性を持つクラスを定義する「バディ・クラス」アプローチ:•属性を持つクラスを継承します。

何か間違っていますか?それともこれは単に不可能なのでしょうか?

私は、次のコードを動作させることができるようにする必要があります:

foreach (PropertyInfo propertyInfo in currentObject.GetType().GetProperties()) 
{ 
    foreach (CustomAttributeData attrData in propertyInfo.GetCustomAttributesData()) 
     { 
      if (typeof(attrData) == typeof(MyAttributeOne)) 
       //stuff 
      else if (typeof(attrData) == typeof(MyAttributeTwo)) 
       //different stuff 
      else 
       //yet more stuff 
     } 
} 

は注意をありがとうございました!よろしくです。 よろしくお願いします。

+2

どのようにメタデータを置くことについてまったく違うクラス? [this](https://msdn.microsoft.com/en-us/library/ee707339(v = vs.91).ASPX)と同じ方法で。 – DavidG

+0

私はそれを試みました.2番目の例は、別のクラスのメタデータですか、別の_file_を意味していますか?それは何か変わるだろうか? – RaulTheThinker

+0

私は、エンティティが継承するものではなく、全く異なるクラスを意味します。 – DavidG

答えて

1

OKこれは少し複雑ですが、それはかなり簡単です。これは実際には脳のダンプのビットですが、それは動作し、あなたに十分な作業を提供します。いくつかの基本を設定しましょう:

//A couple of custom attributes 
public class MyAttributeOne : Attribute { } 
public class MyAttributeTwo : Attribute { } 

//A metadata class where we can use the custom attributes 
public sealed class MyEntityMetadata 
{ 
    //This property has the same name as the class it is referring to 
    [MyAttributeOne] 
    public int SomeProperty { get; set; } 
} 

//And an entity class where we use System.ComponentModel.DataAnnotations.MetadataType 
//to tell our function where the metadata is stored 
[MetadataType(typeof(MyEntityMetadata))] 
public class MyEntity 
{ 
    public int SomeProperty { get; set; } 
} 

[OK]をまだ私と一緒にですか?今、私たちは、あなたがやったのと同じ方法でプロパティを処理する機能を必要とする以前:

public void DoStuff(object currentObject) 
{ 
    //Lets see if our entity class has associated metadata 
    var metaDataAttribute = currentObject.GetType() 
     .GetCustomAttributes() 
     .SingleOrDefault(a => a is MetadataTypeAttribute) as MetadataTypeAttribute; 

    PropertyInfo[] metaProperties = null; 

    //Cache the metadata properties here 
    if (metaDataAttribute != null) 
    { 
     metaProperties = metaDataAttribute.MetadataClassType.GetProperties(); 
    } 

    //As before loop through each property... 
    foreach (PropertyInfo propertyInfo in currentObject.GetType().GetProperties()) 
    { 
     //Refactored this out as it's called again later 
     ProcessAttributes(propertyInfo.GetCustomAttributes()); 

     //Now check the metadata class 
     if (metaProperties != null) 
     { 
      //Look for a matching property in the metadata class 
      var metaPropertyInfo = metaProperties 
       .SingleOrDefault(p => p.Name == propertyInfo.Name); 

      if (metaPropertyInfo != null) 
      { 
       ProcessAttributes(metaPropertyInfo.GetCustomAttributes()); 
      } 
     } 
    } 
} 

そしてもちろん、ここに属性を処理するためのリファクタリング手法である。

private void ProcessAttributes(IEnumerable<Attribute> attributes) 
{ 
    foreach (var attr in attributes) 
    { 
     if (attr is MyAttributeOne) 
     { 
      Console.WriteLine("MyAttributeOne found"); 
     } 
     else if (attr is MyAttributeTwo) 
     { 
      Console.WriteLine("MyAttributeTwo found"); 
     } 
     else 
     { 
     } 
    } 
} 
関連する問題