2010-09-23 28 views
55

Có cách nào tôi có thể có một tập tin được tạo mã như vậy:Tôi có thể định nghĩa các thuộc tính trong các lớp một phần, sau đó đánh dấu chúng với các thuộc tính trong một lớp khác không?

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

và sau đó trong tập tin khác:

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

Vì vậy mà tôi có thể có một lớp được tạo ra từ cơ sở dữ liệu và sau đó sử dụng một tệp không được tạo để đánh dấu nó?

+0

bao nhiêu là "tạo ra từ các cơ sở dữ liệu"? Chỉ định nghĩa thuộc tính hoặc mã là tốt? – snemarch

+1

Câu trả lời ngắn gọn, không. Câu trả lời dài, dup của http://stackoverflow.com/questions/456624/associate-attribute-with-code-generated-property-in-net. –

+0

@snemarch: chỉ định nghĩa thuộc tính, tôi có kế hoạch thực hiện bất kỳ mã nào khác bằng tay. –

Trả lời

24

Tôi đã nhìn thấy một cái gì đó như thế này được thực hiện trong một bài viết của Scott Guthrie (gần cuối của nó) - không thử bản thân mình, mặc dù.
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; } 
} 
+5

Câu trả lời này đề cập đến, nhưng nó không phải là một giải pháp chung cho câu hỏi đặt ra bởi OP. Người tiêu dùng của các thuộc tính vẫn cần biết để tìm kiếm lớp dữ liệu meta - tức là các thuộc tính này sẽ * không * được trả về bởi Attribute.GetCustomAttribute (...). (May mắn thay cho nhiều trường hợp sử dụng, người tiêu dùng được viết bởi MS và trong một số trường hợp, điều này sẽ hoạt động.) –

+0

Giải pháp này KHÔNG giải quyết được vấn đề. Tại sao chúng ta nhìn vào trang trí các thành viên trong một tập tin khác? Bởi vì lớp là OVERWRITTEN mỗi khi người thiết kế chạy. Do đó, thuộc tính của bạn '[MetaDataType ...' sẽ bị xóa mỗi khi nhà thiết kế chạy –

+0

@Desolator - Ý tưởng là bạn không đặt thuộc tính 'MetadataType' trong tệp được tạo bởi nhà thiết kế, bạn đặt nó vào tập tin trong đó lớp một phần 'Person' được định nghĩa. –

0

Không phải như vậy; trình biên dịch sẽ phàn nàn rằng thành viên được định nghĩa trong nhiều phần. Tuy nhiên, vì việc sử dụng các thuộc tính tùy chỉnh phản ánh trong tự nhiên, bạn có thể định nghĩa một lớp "siêu dữ liệu" và sử dụng nó để chứa các trình trang trí.

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

Tần suất mà tác nhân thêm thuộc tính vào thuộc tính của họ cũng là người tiêu thụ chúng và do đó sẽ tìm kiếm các lớp học "Meta" huyền diệu? –

+0

Khá thường xuyên, theo kinh nghiệm của tôi. Điều này sẽ không làm việc cho một khung công tác hướng-khía cạnh hiện có, nhưng nếu bạn đã trang trí tên miền của mình với thuộc tính xác thực tùy chỉnh, bạn là người tìm kiếm chúng và có thể xác định vị trí. Nhóm của tôi đã thực hiện chính xác điều này trên một trong các dự án của chúng tôi. Những bất lợi chính là không tìm kiếm các lớp khác; nó duy trì hai lớp song song trong khi phát triển, một chức năng, trang trí khác. Đó sẽ là một vấn đề trong các lớp học một phần là tốt, nếu bạn đã có thể xác định một phần các lĩnh vực/tài sản ở nơi đầu tiên. – KeithS

53

Tôi biết đây là một câu hỏi cũ, nhưng đây là giải pháp tôi đã được sử dụng cho những trường hợp này. Nó rất hữu ích khi bạn có các lớp được tạo tự động mà bạn muốn trang trí với các thuộc tính. Giả sử đây là lớp được tạo tự động:

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

Và giả sử, tôi muốn thêm thuộc tính để chỉ định UserId là khóa. sau đó tôi sẽ tạo ra một lớp học phần trong một tập tin như thế này:

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

Làm việc như một sự quyến rũ! Cảm ơn bạn!!! –

+0

Giải pháp tuyệt vời. Tôi biết rằng bạn có thể trang trí lớp một phần với các thuộc tính trong nhiều tệp và thậm chí thêm các giao diện và lớp thừa kế vào khai báo của nó, nhưng tôi đã không tạo kết nối đến thuộc tính 'MetadataType'. Làm tốt! – Pflugs

+0

Nếu tôi muốn thêm thuộc tính vào hàm tạo của 'UserProfile' thì sao? – Botis

1

Đây là câu trả lời
file lớp khác nhau của tôi hoặc bạn có thể kết hợp các metadatas trong một tập tin tương tự nhưng giữ không gian tên các same..so họ có thể nhìn thấy nhau rõ ràng.

lưu ý khi bạn cập nhật mô hình của mình như thêm nhiều cột hơn, bạn cũng phải cập nhật lớp dự á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 
{ 
} 
0

Bạn cần phải xác định một lớp học phần cho các lớp học A của bạn giống như bên dưới ví dụ

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; } 
} 
Các vấn đề liên quan