Tôi có thể xác định các thuộc tính trong các lớp một phần, sau đó đánh dấu chúng bằng các thuộc tính trong một lớp một phần khác không?


82

Có cách nào để tôi có thể tạo tệp mã như vậy không:

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

và sau đó trong một tệp khác:

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

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


Bao nhiêu được "tạo ra từ cơ sở dữ liệu"? Chỉ định nghĩa tài sản, hoặc mã là tốt?
Snemarch 23/09/10

1
Câu trả lời ngắn gọn, không. Câu trả lời dài, trùng lặp của stackoverflow.com/questions/456624/… .
Kirk Woll

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

1
Bạn có thể làm gì với một phân tách giao diện + triển khai thay vì một phần lớp không? Tạo giao diện từ cơ sở dữ liệu, triển khai (và thêm các thuộc tính) trong quá trình triển khai.
Snemarch 23/09/10

có điều này là có thể nhưng với việc sử dụng siêu dữ liệu sau đó có kế thừa một phần khác mà siêu dữ liệu
CyberNinja

Câu trả lời:


33

Tôi đã thấy điều gì đó như thế này được thực hiện trong một bài báo của Scott Guthrie (gần cuối của nó) - mặc dù vậy, tôi đã không thử nó.
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
Câu trả lời này được đề cập đến, nhưng nó không phải là một giải pháp chung cho câu hỏi mà OP đặt ra. Người tiêu dùng thuộc tính vẫn cần biết để tìm kiếm lớp dữ liệu meta - tức là những 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 những tình huống nhất định sẽ làm việc này.)
Kirk Woll

1
Giải pháp này KHÔNG giải quyết được vấn đề. Tại sao chúng tôi tìm cách trang trí các thành viên trong một tệp khác? Bởi vì lớp bị QUÁ LẠI mỗi khi trình thiết kế chạy. Như vậy thuộc tính của bạn [MetaDataType ...sẽ bị xóa mỗi lần nhà thiết kế chạy

2
@Desolator - Ý tưởng là bạn không đặt MetadataTypethuộc tính trong tệp được tạo bởi trình thiết kế, bạn đặt thuộc tính đó trong tệp khác nơi lớp một phần Personđược xác định.
Dan Dumitru,

1
vấn đề với giải pháp này là shouldve lớp được một phần
CyberNinja

85

Đây là giải pháp mà tôi đã và đang sử dụng cho những trường hợp như vậy. Nó hữu ích khi bạn có các lớp được tạo tự động mà bạn muốn trang trí bằng 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 một thuộc tính để chỉ định rằng UserId là khóa. Sau đó, tôi sẽ tạo một lớp một phần trong một tệp khác 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; }
    }
}

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

Điều gì xảy ra nếu tôi muốn thêm một thuộc tính vào hàm tạo của UserProfile?
Botis

2
MetadataTypekhông tồn tại trong .NET Lõi
WoIIe

2
sử dụng lõi .netModelMetadataType
YLJ

1
Hỗ trợ @Dave được cho là sẽ có trong .NET Core 3.0
Roger Willcocks

2

Đây là câu trả lời của tôi về
các tệp lớp khác nhau hoặc bạn có thể kết hợp các siêu dữ liệu trong cùng một tệp nhưng giữ nguyên không gian tên..vì vậy chúng có thể nhìn thấy nhau một cách rõ ràng.

hãy ghi nhớ khi bạn cập nhật mô hình của mình, chẳng hạn như thêm nhiều cột, 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
{
}

1

Bạn cần xác định một phần lớp cho Alớp của mình giống như ví dụ dưới đây

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

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 xác định trong nhiều phần. Tuy nhiên, vì việc sử dụng các thuộc tính tùy chỉnh là phản ánh bản chất, bạn có thể xác định 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 đang thêm các thuộc tính vào thuộc tính của mình cũng là người tiêu thụ chúng và do đó sẽ biết cách tìm kiếm các lớp "Meta" ma thuật?
Kirk Woll

Theo kinh nghiệm của tôi, khá thường xuyên. Điều này sẽ không hoạt động đối với một khuôn khổ hướng khía cạnh hiện có, nhưng nếu bạn đang trang trí miền của mình, chẳng hạn như các thuộc tính xác thực tùy chỉnh, bạn là người đang 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 những dự án của chúng tôi. 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 lớp chức năng, lớp kia trang trí. Đó cũng sẽ là một vấn đề trong các lớp từng phần, nếu bạn có thể xác định các trường / thuộc tính một phần ngay từ đầu.
KeithS
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.