2009-06-26 30 views
24

Có cách nào để thêm thuộc tính tùy chỉnh vào các thuộc tính trong mã EF được tạo không? Điều duy nhất tôi có thể xem như là một giải pháp hợp lý sẽ là đưa ra một mẫu T4 tùy chỉnh. Tuy nhiên, do tính chất của thuộc tính nên không thể xác định tham số thuộc tính đúng cho mỗi thuộc tính EF.Thêm các thuộc tính thuộc tính tùy chỉnh trong mã khung thực thể

Trả lời

35

Bạn có thể thực hiện việc này bằng cách chỉ định loại siêu dữ liệu phản ánh thuộc tính và được sử dụng chỉ để phân bổ.

[MetadataType(typeof(Dinner_Validation))] 
public partial class Dinner 
{} 

public class Dinner_Validation 
{ 
    [Required] 
    public string Title { get; set; } 
} 

Steve Smith viết blog về số here.

Thật không may là cách tiếp cận trên là dễ gãy để tái cấu trúc. Một tùy chọn khác là sử dụng các thực thể POCO mới. Những điều này tránh việc tạo mã thời gian biên dịch hoàn toàn theo như tôi có thể nói. Tôi đã không sử dụng chúng được nêu ra như vậy không thể bình luận về bất kỳ cạm bẫy hoặc sự cân bằng.

+0

Tôi đã yêu EF khi tôi đột nhiên nhận ra rằng các thuộc tính trên thực thể của tôi sẽ không thực tế do cách chúng được xử lý. Grrrr. – Chev

+4

Khi phản ánh, 'assembly.GetType (typeof (Dinner) .ToString(). GetProperties()', 'property.Attributes' là null và' property.GetCustomAttributes (typeof (RequiredAttribute)) 'trả về một mảng có độ dài bằng không - nên một phản ánh Dinner_Validation hoặc là một cái gì đó khác awry? – lukiffer

0

Tôi không tin rằng bạn có thể. Trình tạo ra khai báo tất cả các lớp như một phần cho phép bạn mở rộng nó, nhưng nó sẽ không cho phép bạn đánh dấu các thuộc tính với các thuộc tính tùy chỉnh vì nó sẽ đơn giản tạo ra chúng. Một điều bạn có thể làm là viết các thực thể của riêng bạn.

+0

Đây có thể là trường hợp, nhưng có một vài lựa chọn hiện nay. Xem câu trả lời của tôi để biết thông tin. –

8

Bạn có thể tạo giao diện và khai báo thuộc tính trên giao diện.

partial class Person : IPerson {} 

public interface IPerson 
{ 
    [Required] 
    string Name { get; set; } 
} 
+2

Là một lưu ý phụ cho độc giả trong tương lai, điều này không * không * làm việc với xác nhận của asp.net-mvc –

11

Bạn có thể thêm video này vào tập tin EDMX, với thiết kế thêm:

<Property Name="Nome" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" > 
      <Documentation> 
       <Summary>[MyCustomAttribute]</Summary> 
      </Documentation> 
</Property> 

Và thay T4:

void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty) 
{ 
    WriteProperty(Accessibility.ForProperty(edmProperty), 
        code.Escape(edmProperty.TypeUsage), 
        code.Escape(edmProperty), 
        code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
        code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 

Với:

void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty) 
{ 
    if(edmProperty.Documentation != null && string.IsNullOrWhiteSpace(edmProperty.Documentation.Summary) == false) 
    { 
    #> 
    <#=edmProperty.Documentation.Summary#> 
<#+ 
    } 
    WriteProperty(Accessibility.ForProperty(edmProperty), 
        code.Escape(edmProperty.TypeUsage), 
        code.Escape(edmProperty), 
        code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
        code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 
+0

Giải pháp tốt đẹp ... – Omtara

+0

HI, làm thế nào để thay đổi mẫu T4? tạo ra một tập tin Model1.tt và tất cả các văn bản của nó màu đen và có vẻ như một cú pháp khác. – pungggi

2

Bạn có thể thêm này vào tệp EDMX, với Nhà thiết kế cũng:

<Property Name="Nome" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" > 
      <Documentation> 
       <Summary>[MyCustomAttribute]</Summary> 
      </Documentation> 
</Property> 

Và thay T4:

void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty) 
{ 
    WriteProperty(Accessibility.ForProperty(edmProperty), 
        code.Escape(edmProperty.TypeUsage), 
        code.Escape(edmProperty), 
        code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
        code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 

Với:

void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty) 
{ 
    if(edmProperty.Documentation != null && string.IsNullOrWhiteSpace(edmProperty.Documentation.Summary) == false) 
    { 
    #> 
    <#=edmProperty.Documentation.Summary#> 
<#+ 
    } 
    WriteProperty(Accessibility.ForProperty(edmProperty), 
        code.Escape(edmProperty.TypeUsage), 
        code.Escape(edmProperty), 
        code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
        code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 

Và đối với Entity Framework 6, thay thế

public string Property(EdmProperty edmProperty) 
{ 
    return string.Format(
     CultureInfo.InvariantCulture, 
     "{0} {1} {2} {{ {3}get; {4}set; }}", 
     Accessibility.ForProperty(edmProperty), 
     _typeMapper.GetTypeName(edmProperty.TypeUsage), 
     _code.Escape(edmProperty), 
     _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
     _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 

với

public string Property(EdmProperty edmProperty) 
{ 
    var description = String.Empty; 
    bool isAttribute = false; 

    if(edmProperty.Documentation != null && 
     string.IsNullOrWhiteSpace(edmProperty.Documentation.Summary) == false) 
    { 
     string summary = edmProperty.Documentation.Summary; 
     if (!String.IsNullOrEmpty(summary) && summary.First() == '[' && summary.Last() == ']') 
     { 
      isAttribute = true; 
     } 

     if (isAttribute) 
     { 
      description = String.Format("\r\n\t{0}\r\n\t", summary); 
     } 
     else 
     { 
      description = String.Format("\r\n\t/// <summary>\r\n\t/// {0}\r\n\t/// </summary>\r\n\t", 
       summary); 
     } 

    } 

    return string.Format(
     CultureInfo.InvariantCulture, 
     "{5}{0} {1} {2} {{ {3}get; {4}set; }}", 
     Accessibility.ForProperty(edmProperty), 
     _typeMapper.GetTypeName(edmProperty.TypeUsage), 
     _code.Escape(edmProperty), 
     _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
     _code.SpaceAfter(Accessibility.ForSetter(edmProperty)), 
     description); 
} 

Cảnh báo:

  • Namespaces cần phải được giải quyết hoàn toàn.
  • Giả sử các thuộc tính bắt đầu bằng '[' và kết thúc bằng ']' - không có lỗi nào khác kiểm tra
  • Nếu không tìm thấy dấu ngoặc mở và đóng, bản tóm tắt thuộc tính khung thực thể được bao gồm trong nhận xét cắt giảm ba lần XML.
  • Cố gắng kết hợp thông tin tạo kiểu studio trực quan mặc định (thực sự chỉ là thụt lề) có thể có hoặc không có thể là trường hợp cho dự án của bạn. Điều này bao gồm các dòng mới.sản lượng

mẫu:

/// <summary> 
/// content type 
/// </summary> 
public System.Guid ContentType { get; set; } 

[System.ComponentModel.DisplayName("Last Modified")] 
public System.DateTime LastModified { get; set; } 
0

Ngoài trả lời BurnsBA của, Để áp dụng điều này để tính Navigation quá, cập nhật NavigationProperty() cũng như:

public string NavigationProperty(NavigationProperty navProp) 
{ 
    var description = String.Empty; 
    if(navProp.Documentation != null && string.IsNullOrWhiteSpace(navProp.Documentation.Summary) == false) 
    { 
     string summary = navProp.Documentation.Summary; 
     if (!String.IsNullOrEmpty(summary) && summary.First() == '[' && summary.Last() == ']') 
     { 
      description = String.Format("\r\n\t{0}\r\n\t", summary); 
     } 
     else 
     { 
      description = String.Format("\r\n\t/// <summary>\r\n\t/// {0}\r\n\t/// </summary>\r\n\t", summary); 
     } 
    } 

    var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()); 
    return string.Format(
     CultureInfo.InvariantCulture, 
     "{5}{0} {1} {2} {{ {3}get; {4}set; }}", 
     AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)), 
     navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, 
     _code.Escape(navProp), 
     _code.SpaceAfter(Accessibility.ForGetter(navProp)), 
     _code.SpaceAfter(Accessibility.ForSetter(navProp)), 
     description); 
} 

Tôi sử dụng này để thêm [Newtonsoft.Json.JsonIgnore] để tôi tính chất.

Lưu ý: Bạn phải thêm chúng vào <...>Model.tt và không <...>Model.Context.tt

Các vấn đề liên quan