在Entity Framework代码中添加自定义属性属性
是否有任何方法将自定义属性添加到EF生成代码中的属性?我能看到的唯一合理的解决方案是创建一个定制的T4模板。但是,由于属性的性质,不可能为每个EF属性确定正确的属性参数。在Entity Framework代码中添加自定义属性属性
您可以通过指定镜像属性的元数据类型来完成此操作,并且仅用于归因。
[MetadataType(typeof(Dinner_Validation))]
public partial class Dinner
{}
public class Dinner_Validation
{
[Required]
public string Title { get; set; }
}
史蒂夫史密斯博客关于它here。
不幸的是,上述方法对于重构来说很脆弱。另一种选择是使用新的POCO实体。据我所知,这完全避免了编译时代码的产生。我还没有使用它们,所以不能评论任何陷阱或权衡。
我不相信你可以。生成器将所有类声明为partial,允许您扩展它,但不允许您使用自定义属性标记属性,因为它只会生成它们。你可以做的一件事就是编写你自己的实体。
这可能是如此,但也有几个选项现在。查看我的答案获取信息。 – 2010-08-18 21:01:52
您可以在接口上创建接口和声明属性。
partial class Person : IPerson {}
public interface IPerson
{
[Required]
string Name { get; set; }
}
作为未来读者的一个便笺,这不会*与asp.net-mvc的验证工作 – 2014-03-17 22:29:35
你也可以将它添加到EDMX文件,与设计师:
<Property Name="Nome" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" >
<Documentation>
<Summary>[MyCustomAttribute]</Summary>
</Documentation>
</Property>
而更换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)));
}
有了:
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)));
}
您可以添加此EDMX文件,与设计师也:
<Property Name="Nome" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" >
<Documentation>
<Summary>[MyCustomAttribute]</Summary>
</Documentation>
</Property>
而更换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)));
}
有了:
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)));
}
而对于实体框架6,更换
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)));
}
与
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);
}
个
警告:
- 命名空间需要被完全解决。
- 假设属性以'['开始并以']'结尾 - 没有其他错误检查
- 如果未找到开始和结束大括号,则将实体框架属性摘要包装在XML三重斜杠注释中。
- 尝试匹配默认的视觉工作室样式信息(实际上只是缩进),这可能或可能不是您的项目的情况。这包括新行。
输出样本:
/// <summary>
/// content type
/// </summary>
public System.Guid ContentType { get; set; }
[System.ComponentModel.DisplayName("Last Modified")]
public System.DateTime LastModified { get; set; }
除了BurnsBA的答复,要应用此导航性能也更新NavigationProperty()
还有:
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);
}
我使用它来添加[Newtonsoft.Json.JsonIgnore]
我属性。
注意:你必须把这些东西加到<...>Model.tt
而不是<...>Model.Context.tt
我刚刚爱上了EF,当我突然意识到我的实体的属性由于处理方式而实际上不存在。 GRRRR。 – Chev 2010-11-23 07:17:47
当反映时,`assembly.GetType(typeof(Dinner).ToString()。GetProperties()`,`property.Attributes`为null并且`property.GetCustomAttributes(typeof(RequiredAttribute))`返回一个零长度的数组 - 应该一个反映Dinner_Validation或是其他东西是错误的? – lukiffer 2011-06-24 23:13:36