24

はじめに2015年2月まだEntityFrameworkEDMXを使用している場合は、代わりにEntity FrameworkCodeFirstを使用してチェックアウトしてください。違いは、モデルクラスがテーブルで作成されるEDMXではなく、モデルクラスからテーブルが作成されることです。それは万能のより簡単な解決策であり、この質問の問題は存在しません!

MVC5を使用したEntityFramework6コードの開始

既存のSQLデータベースがあり、モデルにADO.NET EnityDataModelを使用しています。いくつかのCRUD機能をMVCアプリケーションに組み込みたいと思っています。

このテーマに関して私が見つけたすべてのチュートリアルでは、モデルを最初から作成し、モデルクラスに属性を追加します。例えば:

    [Required]
    [StringLength(10)]
    public string Name { get; set; }

ただし、モデルクラスは自動生成されるため、変更することはお勧めできません(データベースモデルが更新されると、とにかく上書きされます)。

検証属性を追加するにはどうすればよいですか?

4

5 に答える 5

36

EFで生成されたクラスとは別に、部分的なクラスを作成して、メタデータをに格納できます。

//Contact.cs - The original auto-generated file 
[System.ComponentModel.DataAnnotations.MetadataType(typeof(ContactMetadata))]
public partial class Contact
{
    public int ContactID { get; set; }
    public string ContactName { get; set; }
    public string ContactCell { get; set; }
}

//ContactMetadata.cs - New, seperate class

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
internal sealed class ContactMetadata
{
    [Required(ErrorMessage = "Name is required.")]
    [StringLength(5)]  
    public string ContactName;
}
于 2012-12-27T19:03:46.233 に答える
19

Mason240の答えはうまく機能します、私はそれを改善しようとします:あなたは新しいContactDataAnnotations.csクラスを作成することができます:

//ContactDataAnnotations.cs - A new file 
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

[MetadataType(typeof(ContactMetadata))]
public partial class Contact
{
    // No field here
}

internal sealed class ContactMetadata
{
    [Required(ErrorMessage = "Name is required.")]
    [StringLength(5)]  
    public string ContactName {get; set; }
}

このようにして、DataAnnotationsに触れることなく、また警告なしに、EFを介してContactクラスを再生成できます。

于 2014-04-25T10:46:30.667 に答える
4

これはすでに正しく答えられていますが、メタデータのネストは私には少しすっきりしているように思えたことも付け加えておきたいと思います。

[MetadataType(typeof(ProductDescription.Metadata))]
public partial class ProductDescription
{
    sealed class Metadata
    {
        [Key]
        public long id { get; set; }
        [Display(Name = "Title")]
        public string title { get; set; }
        // ...
    }
}

また、メタデータをクラスに対してプライベートに保つことの追加の利点にも気づきました。この属性は正しいクラスでのみ機能し、クラスを複製した場合に発生する可能性のあるバグを防ぎます(同様のクラスを作成するため)。複製されたクラスの名前を変更するときに属性のクラス名を変更するのを忘れた場合、バグが発生する可能性があります。

于 2015-04-01T01:25:09.903 に答える
4

私はこれが回答済みとマークされていることを知っていますが、いくつかのものを片付けたいと思います。

@SteveCavは、「このメンバーは複数回定義されています」と述べています。まったく同じエラーが発生しました。理解しようとして何時間も費やしました。

最終的に修正するには、同じアセンブリ内に別のファイルクラスを作成する必要があります(これはすでにここで説明されていると思います)。しかし、私が強調したいのは、このクラスは、内部クラスを表す部分クラスとネストする必要があるということです。

次に、その内部クラスをAnnotationクラスで装飾します。このような:

//ContactMap.cs - Present in the same namespace as Contact.cs
[System.ComponentModel.DataAnnotations.MetadataType(typeof(ContactMap))]
partial class Contact // Present in the ContactMap class. This represent the Inner Class
{
}

//ContactMap.cs - This represent the outer class

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public class ContactMetadata
{
    [Required(ErrorMessage = "Name is required.")]
    [StringLength(5)]  
    public string ContactName;
}

これがより明確またはより理解しやすいことを願っています。

于 2015-04-22T13:08:53.557 に答える
3

ここでは、さまざまなアセンブリと名前空間でクラスを使用できるようにする、提案された回答のバリエーションがあります。EFで実際にテストしたことはありませんが、SwaggercodegenAPIモデルクラスにこれを使用しています。

簡単に言うと、モデルクラスから継承し、継承されたクラスにメタデータを追加します。追加の利点は、Swagger codegenを使用すると、マッピングなしでAPIモデルを直接使用でき、初期フォームには保護されたデフォルトのctorを使用できることです。

[MetadataType(typeof(LocalAssemblyModelMetadata))]
public class LocalAssemblyModel : IO.Swagger.Model.OtherAssemblyModel 
{
    public LocalAssemblyModel() : base ()     { }
}



public sealed class LocalAssemblyModelMetadata
{
    [Required(ErrorMessage = "BaseclassProperty is mandatory.")]
    public string BaseclassProperty { get; set; }
}
于 2016-10-05T08:36:21.833 に答える