Kısmi sınıflarda özellikler tanımlayıp daha sonra bunları başka bir kısmi sınıftaki niteliklerle işaretleyebilir miyim?


84

Oluşturulmuş bir kod dosyasına sahip olabilmemin bir yolu var mı:

public partial class A {
public string a {get; set;}
}

ve sonra başka bir dosyada:

public partial class A {
[Attribute("etc")]
public string a {get; set;}
}

Veritabanından oluşturulmuş bir sınıfa sahip olabilmem ve ardından onu işaretlemek için oluşturulmamış bir dosyayı kullanabilmem için?


"Veritabanından ne kadar üretilir"? Sadece mülk tanımları mı yoksa kod mu?
snemarch

1
Kısa cevap, hayır. Uzun cevap, stackoverflow.com/questions/456624/… .
Kirk Woll

@snemarch: yalnızca mülkiyet tanımları, başka herhangi bir kodu elle yapmayı planlıyorum.
Chris McCall

1
Kısmi sınıf yerine arayüz + uygulama ayrımı yapabilir misiniz? Arayüzü veritabanından oluşturun, uygulamada uygulayın (ve öznitelikler ekleyin).
snemarch

evet bu mümkündür, ancak meta verilerin kullanımıyla diğer kısmi bu meta veriyi devralın
CyberNinja

Yanıtlar:


33

Scott Guthrie tarafından yazılan bir makalede buna benzer bir şey gördüm (sonlarına doğru) - yine de kendim denemedim.
http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

[MetadataType(typeof(Person_Validation))]
public partial class Person
{
    // Partial class compiled with code produced by VS designer
}

[Bind(Exclude="ID")]
public class Person_Validation
{
    [Required(ErrorMessage = "First Name Required")]
    [StringLength(50, ErrorMessage = "Must be under 50 characters")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Last Name Required")]
    [StringLength(50, ErrorMessage = "Must be under 50 characters")]
    public string LastName { get; set; }

    [Required(ErrorMessage = "Age Required")]
    [Range(0, 120, ErrorMessage = "Age must be between 0 and 120")]
    public int Age { get; set; }

    [Required(ErrorMessage = "Email Required")]
    [Email(ErrorMessage = "Not a valid email")]
    public string Email { get; set; }
}

10
Bu cevap zikredilmeyi gerektirir, ancak OP'nin sorduğu soruya genel bir çözüm değildir. Tüketiciler hala meta veri sınıfına aramaya bilmek gerekir niteliklerini - yani bu özelliklerin olacak değil Attribute.GetCustomAttribute (...) tarafından iade edilmesi. (Neyse ki birçok kullanım durumu için, tüketiciler MS tarafından yazılmıştır ve bazı durumlarda bu işe yarayacaktır.)
Kirk Woll

1
Bu çözüm sorunu çözmez. Üyeleri neden başka bir dosyada dekore etmeye çalışıyoruz? Çünkü tasarımcı her çalıştığında sınıf OVERWRITTEN olur. Böylece [MetaDataType ..., tasarımcı her çalıştığında niteliğiniz temizlenecektir

2
@Desolator - Fikir, MetadataTypeözniteliği tasarımcı tarafından oluşturulan dosyaya koymamanız , onu kısmi sınıfın Persontanımlandığı diğer dosyaya koymanızdır .
Dan Dumitru

1
bu çözümle ilgili sorun, sınıfın kısmi olması gerektiğidir
CyberNinja

85

İşte bu tür durumlar için kullandığım çözüm. Özniteliklerle süslemek istediğiniz otomatik oluşturulmuş sınıflarınız olduğunda kullanışlıdır. Diyelim ki bu otomatik olarak oluşturulmuş sınıf:

public partial class UserProfile
{
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

Ve diyelim ki, UserId'nin anahtar olduğunu belirtmek için bir özellik eklemek istiyorum. Daha sonra bunun gibi başka bir dosyada kısmi bir sınıf oluştururdum:

[Table("UserProfile")]
[MetadataType(typeof(UserProfileMetadata))]
public partial class UserProfile
{
    internal sealed class UserProfileMetadata
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
    }
}

Harika çözüm. Kısmi sınıfı birden çok dosyadaki özniteliklerle dekore edebileceğinizi ve hatta bildirimine arayüzler ve miras alınmış bir sınıf ekleyebileceğinizi biliyordum, ancak MetadataTypeözniteliğe bağlantı yapmadım . Aferin!
Pflugs

Yapıcıya bir öznitelik eklemek istersem ne olur UserProfile?
Botis

2
MetadataType.NET Core'da mevcut değil
WoIIe

2
.net çekirdek kullanırModelMetadataType
YLJ

1
@Dave Support'un .NET Core 3.0'da gelmesi bekleniyor
Roger Willcocks

2

Bu benim cevabım
farklı sınıf dosyaları veya metadataları aynı dosyada birleştirebilir, ancak ad alanını aynı tutabilirsiniz .. böylece birbirlerini açıkça görebilirler.

modelinizi güncellediğinizde daha fazla sütun eklediğinizde proje sınıfını da güncellemeniz gerektiğini unutmayın.

--your model class
public partial class A {
    public string a {get; set;}
}

--your project class 
public class Ametadata {
     [Attribute("etc")]
     public string a {get; set;}
}


[MetadataType(typeof(Ametadata))]
public partial class A
{
}

1

AAşağıdaki örnekte olduğu gibi sınıfınız için kısmi bir sınıf tanımlamalısınız

using System.ComponentModel.DataAnnotations;

// your auto-generated partial class
public partial class A 
{
    public string MyProp { get; set; }
}

[MetadataType(typeof(AMetaData))]
public partial class A 
{

}

public class AMetaData
{
    [System.ComponentModel.DefaultValue(0)]
    public string MyProp { get; set; }
}

0

Öyle değil; derleyici, üyenin birden çok kısımda tanımlandığından şikayet edecektir. Ancak, özel özniteliklerin kullanımı doğası gereği yansıtıcı olduğundan, bir "meta veri" sınıfı tanımlayabilir ve bunu dekoratörleri içermek için kullanabilirsiniz.

public class A
{
   public string MyString;
}

public class AMeta
{
   [TheAttribute("etc")]
   public object MyString;
}

...

var myA = new A();
var metaType = Type.GetType(myA.GetType().Name + "Meta");
var attributesOfMyString = metaType.GetMember("MyString").GetCustomAttributes();

1
Özelliklerini mülklerine ekleyen aktör aynı zamanda onları tüketen kişidir ve bu nedenle sihirli "Meta" sınıflarını aramayı bilecektir?
Kirk Woll

Tecrübelerime göre oldukça sık. Bu, mevcut bir bakış açısına yönelik çerçeve için işe yaramaz, ancak alanınızı örneğin özel doğrulama özellikleriyle dekore ediyorsanız, onları arayan sizsiniz ve nerede olduğunu tanımlayabilirsiniz. Ekibim bunu projelerimizden birinde yaptı. Ana dezavantaj, diğer sınıfı aramamaktır; geliştirirken biri işlevsel, diğeri dekoratif olmak üzere iki paralel sınıfı korumaktadır. İlk etapta kısmi alanları / özellikleri tanımlayabilseydiniz, bu kısmi sınıflarda da sorun olurdu.
KeithS
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.