我有一个从数据库创建的edmx
模型和一个元数据.cs。
在客户端中,.g.cs
包括[StringLength(X)]
属性以及元数据中的我的属性。
我正在为一个平面文件导入做一些服务器端验证,该导入与这些实体的客户端编辑器分离。
我可以应用范围和正则表达式验证,但在服务器上找不到StringLength属性。有人知道如何在不手动复制元数据属性上的StringLength属性的情况下做到这一点吗。
编辑:
这里有一些代码:
服务器端文件ProductService.metadata.cs:
internal sealed class PRODUCTMetadata
{
[Required]
[RegularExpression("[A-Z]+")]
[Display(Name = "Product Code", Order = 10)]
public string Product_code { get; set; }
}
客户端Generated_Code\NameSpace.Web.g.cs:
public sealed class PRODUCT
{
[DataMember()]
[Display(Name="Product Code", Order=10)]
[RegularExpression("[A-Z]+")]
[Required()]
[StringLength(8)] //This is what I want to know, but server side
public string Product_code
{...etc
}
}
我已经围绕这个问题进行了一些调查,但在互联网上找不到任何关于这个主题的好信息。所以我在这里说的只是假设。
正如您所看到的,与服务器端代码相比,自动生成的客户端代理代码更多地使用属性进行修饰。例如,您的实体具有来自实体模型的漂亮的[StringLength(8)]
属性。在服务器端,自动生成的.metadata.cs
文件在实体上没有这些属性我认为这一切都与代码生成模板有关。
我怀疑RIAServices的代码生成模板(创建.g.cs
文件)比在服务器端创建.metadata.cs
文件的模板要完整得多。
事实上,在您的案例中丢失的属性是客户端UI验证所用时间的95%,这可能解释了为什么.metadata.cs
文件的模板没有生成验证属性。
我看到你的问题有两个解决办法:
1.在服务器端编写自己的元数据类
例如:
[MetadataTypeAttribute(typeof(PRODUCT.PRODUCTMetadata))]
public partial class PRODUCT
{
internal sealed class PRODUCTMetadata
{
// Metadata classes are not meant to be instantiated.
private PRODUCTMetadata()
{
}
[StringLength(8)]
public string Product_code { get; set; }
}
}
您可以手动将任何属性添加到实体的属性中,因为实体是分部类。
不幸的是,每次修改模型时都必须维护这些元数据:例如,如果DB表列从varchar(8)
更改为varchar(10)
,则可以从数据库中自动更新EDMX模型,但必须手动检查元数据是否仍然正常(在本例中,您必须手动将[StringLength(8)]
替换为[StringLength(9)]
)。
这里有一个关于元数据的好链接。
2.修改T4模板
第二种选择可能是最好的一种,但我自己没有经历过代码生成模板的修改,所以我不知道什么可以有效地完成。
代码生成模板被称为T4模板(文本模板转换工具包)。可以修改这些模板,以便在代码生成过程中包含您想要的任何内容。您可以修改默认的EF模板,使其像RIA服务模板一样生成缺少的属性。
下面是一些关于T4代码生成的好文章:
- http://www.scip.be/index.php?Page=ArticlesNET36#T4CodeGenerationClasses
- http://msdn.microsoft.com/en-us/data/gg558520
- http://msdn.microsoft.com/en-us/library/cc982041.aspx
我写这篇文章是为了回答(不适合作为评论),但请记住,这都是假设。