Varlık çerçevesi tarafından oluşturulan bir sınıfa veri ek açıklamaları ekleyin


93

Varlık çerçevesi tarafından oluşturulan aşağıdaki sınıfa sahibim:

public partial class ItemRequest
{
    public int RequestId { get; set; }
    //...

Bunu zorunlu bir alan yapmak istiyorum

[Required]
public int RequestId { get;set; }

Ancak, bu kod üretildiği için silinecektir. Özellik, oluşturulan kısmi sınıf tarafından tanımlandığı için kısmi bir sınıf oluşturmanın bir yolunu hayal edemiyorum. Kısıtlamayı güvenli bir şekilde nasıl tanımlayabilirim?


Mülkünüz int ise, varsayılan olarak modelbinder için gereklidir, bu nedenle [Gerekli] özniteliğiniz buraya hiçbir şey eklemeyecektir.
Kirill Bestemyanov

@KirillBestemyanov - @ Html.ValidationMessageFor (model => model.Item.Item.ResourceTypeID) istemci tarafında başarısız olmalıdır. O değil.
P. Brian.Mackey

Yanıtlar:


143

Oluşturulan sınıf ItemRequesther zaman bir partialsınıf olacaktır. Bu, gerekli veri açıklamaları ile işaretlenmiş ikinci bir kısmi sınıf yazmanıza izin verir. Sizin durumunuzda kısmi sınıf ItemRequestşöyle görünecektir:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

//make sure the namespace is equal to the other partial class ItemRequest
namespace MvcApplication1.Models 
{
    [MetadataType(typeof(ItemRequestMetaData))]
    public partial class ItemRequest
    {
    }

    public class ItemRequestMetaData
    {
        [Required]
        public int RequestId {get;set;}

        //...
    }
}

11
Kısmi sınıf yeniden oluşturulmayacaktır. Kısmi olarak tanımlanmasının nedeni budur.
MUG4N

kısmi değiştiriciyi kaçırdınız mı? Aynı ad alanını kullanıyor musunuz?
MUG4N

5
.NET Core kullanıcıları: MetadataType yerine ModelMetadataType'ı kullanın.
Bob Kaufman

1
Ad

40

As MUG4N cevap kullanabilirsiniz kısmi sınıfları ama daha iyi kullanılması olacak arayüzleri yerine. Bu durumda, EF modeli doğrulama modeline karşılık gelmezse derleme hatalarınız olur. Böylece, doğrulama kurallarının geçerliliğini yitirmesinden korkmadan EF modellerinizi değiştirebilirsiniz.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace YourApplication.Models
{
    public interface IEntityMetadata
    {
        [Required]
        Int32 Id { get; set; }
    }

    [MetadataType(typeof(IEntityMetadata))]
    public partial class Entity : IEntityMetadata
    {
        /* Id property has already existed in the mapped class */
    }
}

PS ASP.NET MVC'den farklı bir proje türü kullanıyorsanız (manuel veri doğrulaması yaptığınızda) doğrulayıcılarınızı kaydetmeyi unutmayın

/* Global.asax or similar */

TypeDescriptor.AddProviderTransparent(
    new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Entity), typeof(IEntityMetadata)), typeof(Entity));

@dimonser güzel bir çözüm, bunun gibi xml yorumları eklemeyi denedim (kodda küçük bir açıklama gerektiren DB alanları için - yani intellitype'da görüntülenmek için) ama işe yaramıyor. Bunu nasıl yapacağına dair bir fikrin var mı?
Percy

Merhaba @Rick, bir arabirim özelliğine bir yorum koyabilirsiniz, ancak bunu yalnızca bir arabirim değişkeniyle çalışırken göreceksiniz. Ya da kısmi bir sınıfa yorum yazabilirsiniz. Bu durumda, sınıfınızın bir örneğiyle çalışırken göreceksiniz. Başka vaka yok. Böylece her ikisini de tüm durumları kapsamak için kullanabilirsiniz, İlk durumda alan doğrulama kurallarını tanımlayabilir ve ikinci durumda amaçları tanımlamaya çalışabilirsiniz
dimonser

Gerçekten iyi düşünülmüş bir cevap, ancak benim tercihim, doğrulama otomatik olarak oluşturulan varlık çerçeve sınıfıyla artık senkronize değilse derleme hatalarını görmek olacaktır. Varlık çerçeve sınıfınızda artık mevcut olmayan bir özelliği doğrulamak isteyebileceğiniz bir durum düşünmek için uğraşıyorum.
Mike

1
Bu benim için çalışmıyor, IEntityMetadata arayüzünü uygulamam gerektiğini söylüyor ...
Worthy7

14

MUG4N'nin cevabı gibi bir çözüm buldum , ancak bunun yerine MetaDatasınıfı varlık sınıfının içine yerleştirerek, böylece genel ad alanı listenizdeki sınıfların sayısını azaltarak ve her meta veri sınıfı için benzersiz bir ada sahip olma ihtiyacını ortadan kaldırdım.

using System.ComponentModel.DataAnnotations;

namespace MvcApplication1.Models 
{
    [MetadataType(typeof(MetaData))]
    public partial class ItemRequest
    {
        public class MetaData
        {
            [Required]
            public int RequestId;

            //...
        }
    }
}

Bunu projemin her yerinde kullanıyorum. Organize etmek çok daha kolay. Ayrıca [NotMapped], ihtiyacım olduğunda kısmi sınıfın içini kullanarak özel özellikler de ekliyorum .
Carter Medlin

5

Bu, db modelinizi yeniden oluşturursanız, bu sınıflara arayüzleri manuel olarak yeniden eklemeniz gerekecek @dimonser yanıtına bir tür uzantıdır.

Bunun için mideniz varsa, .ttşablonlarınızı da değiştirebilirsiniz :

Aşağıda, bazı sınıflarda otomatik olarak oluşturulan arabirimlerin örneği, bu, sizin yönteminizdeki yöntemi aşağıdakiyle (ve tabii ki varlık adlarınız ve arabirimlerinizle) .ttdeğiştirmenin bir parçasıdır .EntityClassOpeningvar stringsToMatch

public string EntityClassOpening(EntityType entity)
{
    var stringsToMatch = new Dictionary<string,string> { { "Answer", "IJourneyAnswer" }, { "Fee", "ILegalFee" } };
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}{4}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        _code.Escape(entity),
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)),
        stringsToMatch.Any(o => _code.Escape(entity).Contains(o.Key)) ? " : " + stringsToMatch.Single(o => _code.Escape(entity).Contains(o.Key)).Value : string.Empty);
}

Hiçbir normal insan bunu kendi başına yapmamalıdır, İncil'de birinin bunun için Cehenneme gittiği kanıtlanmıştır.


2

İstediğiniz şeyi nasıl yapacağımdan emin değilim ama bunun etrafında bir yol var. Özel DataAnnotationsModelValidatorProvider'ınızın GetValidator'larını geçersiz kılarak dinamik veri doğrulama. İçinde her alanı (bir veritabanından, yapılandırma dosyasından, vb.) Doğrulamak için kuralları okuyabilir ve gerektiği gibi doğrulayıcılar ekleyebilirsiniz. Doğrulamanızın artık modele sıkı sıkıya bağlı olmadığı ve siteyi yeniden başlatmaya gerek kalmadan değiştirilebileceği ek değerlere sahiptir. Elbette sizin durumunuz için aşırı olabilir, ama bizim için idealdi!


Bu yapıyı ilk uyguladığımızda yaptık. O zamandan beri NHibernate'e geçtik, ancak bunun çözüme bir ilgisi yok. Doğrulama kodumuz, herhangi bir değişiklik olmadan olduğu gibi çalıştı (yalnızca veri erişim katmanı değiştirildi).
JTMon

1

T4 şablonunu gerekli ek açıklamaları ekleyerek değiştirin, bu dosya genellikle MODELNAME.tt olarak adlandırılır.

T4'ün sınıfı nerede yarattığını bulun ve bunları nereye koyacağınızı bilmek için yöntemler.

     <#=codeStringGenerator.IgnoreJson(navigationProperty)#>


//create this method in file
public string IgnoreJson(NavigationProperty navigationProperty){
            string result = navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? "" : @"[JsonIgnore]
    [IgnoreDataMember]";

            return result;
        }

Ayrıca ad alanlarını da eklemeniz gerekecektir;

<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using System.Runtime.Serialization;

Modelinizi kaydederek sınıflarınızı yeniden oluşturun, tüm yöntemleriniz açıklanmalıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.