1
votes

Comment mettre à jour (en fusionnant) edmx sans remplacer les classes de modèle dans asp.net mvc

Je développe une application dans asp.net mvc. J'utilise le cadre d'entité comme ORM. J'ai un problème. Pour utiliser la validation javascript discrète, je dois ajouter une annotation aux objets de modèle. Par exemple; [Obligatoire], [EMailAddress]. Mais lorsque nous ajoutons quelque chose à la base de données et la mettons à jour, toutes les classes de modèle sont remplacées et toutes les annotations disparaissent. Ou, dès que vous ouvrez edmx, les classes de modèle automatiques sont automatiquement remplacées. Comment puis-je résoudre ce problème. Il existe des dizaines d'écrans et de classes, le moindre changement dans edmx efface l'annotation dans toutes les classes, ce qui entraîne une énorme perte de temps.

  // GET: Survey
    public ActionResult GetData()
    {
        using (MerinosSurveyEntities entity = new MerinosSurveyEntities())
        {
            List<Surveys> surveys = entity.Surveys.Where(x => x.IsActive && x.Status)
                .OrderBy(x => x.SurveyId).ToList();
            return Json(new { data = surveys }, JsonRequestBehavior.AllowGet);
        }
    }

Modifié pour Métadonnées

Surveys Partial & Metadata

 //PartialClass
 [MetadataType(typeof(SurveyMetadata))]
 public partial class Surveys
{
}
//Metadata
 public partial class SurveyMetadata
{
    public int SurveyId { get; set; }
    [Required(ErrorMessage = "Lütfen anket adını giriniz.")]
    public string SurveyName { get; set; }
    [Required(ErrorMessage = "Lütfen anket açıklamasını giriniz.")]
    public string SurveyDescription { get; set; }

    // [DataType(DataType.Date)]
    public System.DateTime? CreatedDate { get; set; }
    //[DataType(DataType.Date)]

    public System.DateTime? UpdatedDate { get; set; }
    public int CreatedUserId { get; set; }
    public bool IsActive { get; set; }
    public bool Status { get; set; }

    public virtual ICollection<SurveyQuestionMetadata> SurveyQuestionMetadatas { get; set; }
    public virtual ICollection<SurveyCustomerMetadata> SurveyCustomerMetadatas { get; set; }

    public string Token { get; set; }
}

GetData Ajax Event p>

// <auto-generated>

using System.ComponentModel.DataAnnotations;

namespace MerinosSurvey.Models
{
using System;
using System.Collections.Generic;

public partial class Surveys
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Surveys()
    {
        this.SurveyQuestions = new HashSet<SurveyQuestions>();
        this.SurveyCustomers = new HashSet<SurveyCustomers>();
    }

    public int SurveyId { get; set; }
    [Required(ErrorMessage = "Plase enter survey name.")]
    public string SurveyName { get; set; }
    [Required(ErrorMessage = "Please enter survey description.")]
    public string SurveyDescription { get; set; }

    // [DataType(DataType.Date)]
    public System.DateTime? CreatedDate { get; set; }
    //[DataType(DataType.Date)]

    public System.DateTime? UpdatedDate { get; set; }
    public int CreatedUserId { get; set; }
    public bool IsActive { get; set; }
    public bool Status { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<SurveyQuestions> SurveyQuestions { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<SurveyCustomers> SurveyCustomers { get; set; }

    public string Token { get; set; }
}
}

Comment changer mon événement GetData, et quelle liste doit aller côté client ??


1 commentaires

N'utilisez pas de classes d'entité EF dans vos vues. Créez des classes de modèle de vue pour l'interaction de vue du contrôleur <->, y compris les attributs de validation. Les didacticiels MVC aiment garder les choses à plat, mais c'est juste pour réduire la complexité pour des raisons de démonstration.


3 Réponses :


0
votes

La meilleure pratique consiste à utiliser ViewModel [pas des classes d'entité / modèle] pour manipuler / jouer du côté client.

Utilisez donc ViewModel, Inherit Model classes puis utilisez Annotations Pour par exemple. Classe publique ViewModelClass: ModelClass { [Obligatoire ("Le prénom est obligatoire")] Public String FirstName {get; ensemble;} }


9 commentaires

Alors, comment puis-je résoudre ce problème avec un minimum de modifications, le simple fait d'hériter de nouvelles classes résoudra mon travail d'une manière simple.


@ MehmetŞükrüMUMBUÇOĞLU S'il vous plaît voir mon exemple, Créer une nouvelle classe, hériter de la classe Model ou copier-coller toutes les propriétés de Model à Cette classe, ajoutez maintenant vos annotations. Parce que demain, vous allez faire face à de sérieux problèmes, si vous comptez utiliser uniquement des classes de modèle, cette fois, vous devrez utiliser des classes non modèles


À partir de maintenant, j'ai 10 tables. La première phase du projet est terminée. En attendant, je peux apporter des modifications. Je n'ai pas besoin de beaucoup de changement, je pense que la table Survey changera en tant que SurveyViewModel. De plus, comme les relations fk entre les tables sont certaines lors de la création de tables, les classes de modèle sont également conçues automatiquement en conséquence.


@shyamsundarsinghtomar Alors, comment puis-je résoudre ce problème avec un minimum de modifications, le simple fait d'hériter de nouvelles classes résoudra mon travail d'une manière simple. Par exemple, deux heures, j'ai 10 tables dont 5 tables de relations.


Mon approche est plus flexible, vous avez pris de mauvaises décisions plus tôt, je comprends que c'est de la douleur, mais croyez-moi, cela vous évitera des désastreux. Vous pouvez également essayer ceci docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started‌ /… . Vérifiez la partie Métadonnées.


J'espère que cela vous aide. Votez si cela aide


@shyamsundarsinghtomar J'ai créé 2 fichiers nommés une métadonnée et une classe partielle. J'ai ajouté 10 classes de métadonnées pour 10 tables. J'ai ajouté tous les champs de la classe de modèle lors de la copie dans la classe de métadonnées. Je me demande si je fais mal. J'ai ajouté tous les champs, le constructeur, les définitions de liste, le tout dans la classe de métadonnées. Est-ce une méthode correcte car les relations fk dans la base de données ont été déplacées dans des classes de modèle.


Continuons cette discussion dans le chat .


Merci frere. Si vous aimez la question, vous pouvez voter pour ma question



0
votes

Pour faire une telle chose, vous pouvez utiliser des classes partielles et utiliser "ModelMetadataType" dans l'annotation .net core au-dessus de votre classe. faisons-le dans le code: c'est votre modèle qui est créé dans edmx:

public class StudentMetaData{
     [Display(name="First Name")]
     public string FirstName {get; set;}
}

tout d'abord vous devez créer une classe partielle dans un autre fichier avec le même nom que la classe étudiante et faire attention que son espace de nom doit être le même au-dessus de la classe. (les classes doivent être hors du fichier edmx)

[ModelMetadataType(typeof(StudentMetaData))]
public partial class Student{

}

et à la fin vous devez créer votre classe de métadonnées comme ceci:

public partial class Student{
     public string FirstName {get; set;}
}

vous pouvez maintenant mettre à jour votre fichier edmx sans changer les annotations de données dans vos classes de métadonnées.

https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.metadatatypeattribute?view=frfr 4.8


8 commentaires

quelqu'un d'autre a posé mon problème sur cette page . Et EF génère des classes partielles par défaut. Vous pouvez donc placer votre logique dans une "classe d'amis" qui ne sera pas écrasée. écrit. Le framework Entity crée-t-il vraiment des classes de modèle de vue partielle?


Le framework d'entité ne crée pas du tout de classes de «modèle de vue». Ce sont des classes entity .


vous pouvez créer une copie de votre classe et faire comme indiqué facilement. si vous rencontrez un problème, nous pouvons le résoudre facilement


@Jafarashrafi Dois-je créer la classe de métadonnées en tant que classe ou interface? Est-ce que cela m'importe?


@Jafarashrafi Je veux aussi demander une dernière chose. Je devrais ajouter tous les attributs de la classe de modèle d'entité à la classe de métadonnées, non? Y compris les listes. Si je n'ajoute pas les listes, tout sera cassé côté client. Par exemple, la liste SurveyCustomers dans mon modèle ci-dessus


vous n'avez pas besoin d'ajouter toutes les propriétés dans votre classe de métadonnées. vous pouvez utiliser des listes comme vous utilisiez auparavant si vous en ajoutez ou non. la classe de méta-données est une métadonnée et votre classe principale est celle qui a été créée dans edmx


d'accord OK. Par exemple, une fonction que j'apporte à l'écran avec ajax est getData. Dois-je changer cela? Le côté client (dans View) doit-il donc être des objets de métadonnées? Par exemple // GET: Survey public ActionResult GetData () {using (MerinosSurveyEntities entity = new MerinosSurveyEntities ()) {List survey = entity.Surveys.Where (x => x.IsActive && x .Status) .OrderBy (x => x.SurveyId) .ToList (); return Json (new {data = sondages}, JsonRequestBehavior.AllowGet); }}


N'oubliez pas que la classe de métadonnées n'est qu'une métadonnée et qu'elle décrit certaines informations sur les propriétés ou les classes et qu'elle n'affecte jamais votre entreprise et même obtenir ou publier. votre classe principale est responsable de cela. vous ne devez jamais écrire aucune entreprise dans la classe de métadonnées



0
votes

Travaille en mémoire pour le moment, mais les classes EF sont toujours partielles, alors créez une autre implémentation partielle de la même classe, puis ajoutez la liaison Interface et Metadatype à cela.

// Entity Framework Model
public partial class User
{
    public string Email { get; set; }
    public string Password { get; set; }
}

// Your Interface with data annotations
public interface IUser
{
    [Required]
    string Email { get; set; }

    [Required]
    string Password { get; set; }
}

// Partial Model appling the interface to the entity model
[MetadataType(typeof(IUser))]
public partial class User : IUser
{
}

Sous ceci approche, à l'avenir, vous n'aurez plus qu'à vous soucier de la mise à jour de votre interface si vous ajoutez de nouvelles propriétés


2 commentaires

Dois-je créer la classe de métadonnées en tant que classe ou interface? Est-ce que cela m'importe?


Je le créerais comme interface car il sépare les préoccupations entre l'objet entité et les annotations de données tout en vous permettant de consommer l'objet entité.