如何以编程方式从一组现有 POCO 对象生成 CSDL 或 EDMX
我想模拟 WCF 数据服务使用它的“$metadata”标签所做的事情...也就是说,发送一个 CSDL 文档,该文档描述一组现有的对象,这些对象可能是(也可能不是)实体框架模型的一部分。事实上,假设 EF 不属于本次讨论的一部分...
我想创建一个服务来检查它可以返回的对象的类型,生成一个 CSDL 文档并将其发送到客户端,以便客户端可以生成代码来自 CSDL 的那些对象(使用 EDMGen 应该可以)。一旦客户端生成了对象(并加载了生成的程序集),它就可以从服务接收强类型数据。
EDMGen 似乎不能用于从 POCO 生成 CSDL(或 EDMX)...它可以从数据库连接执行此操作,并且您可以从 CSDL 生成 POCO,但不能以其他方式生成。有没有人知道的方法?
具体示例
给定此代码:
public class DirectoryEntry
{
public int Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public ICollection<DirectoryEntryProperty> Properties { get; set; }
}
public class DirectoryEntryProperty
{
public int Id { get; set; }
public string Key { get; set; }
public string Value { get; set; }
public DirectoryEntry DirectoryEntry { get ; set; }
}
我想生成此文档:
<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" Namespace="DirectoryService" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:ib10="http://www.ideablade.com/edm/2010" ib10:Tag="DirectoryService">
<EntityContainer Name="DirectoryServiceContainer" annotation:LazyLoadingEnabled="true" ib10:GenerateDeveloperClasses="true" ib10:DevForceEnabled="false">
<EntitySet Name="DirectoryEntries" EntityType="DirectoryService.DirectoryEntry" />
<EntitySet Name="DirectoryEntryProperties" EntityType="DirectoryService.DirectoryEntryProperty" />
<AssociationSet Name="DirectoryEntryPropertyDirectoryEntry" Association="DirectoryService.DirectoryEntryPropertyDirectoryEntry">
<End Role="DirectoryEntryProperty" EntitySet="DirectoryEntryProperties" />
<End Role="DirectoryEntry" EntitySet="DirectoryEntries" />
</AssociationSet>
</EntityContainer>
<EntityType Name="DirectoryEntry">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Type="String" Name="Name" Nullable="false" />
<Property Type="String" Name="Type" Nullable="false" />
<NavigationProperty Name="Properties" Relationship="DirectoryService.DirectoryEntryPropertyDirectoryEntry" FromRole="DirectoryEntry" ToRole="DirectoryEntryProperty" ib10:Tag="DirectoryEntryPropertyCollectionHelper" />
</EntityType>
<EntityType Name="DirectoryEntryProperty">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<NavigationProperty Name="DirectoryEntry" Relationship="DirectoryService.DirectoryEntryPropertyDirectoryEntry" FromRole="DirectoryEntryProperty" ToRole="DirectoryEntry" />
<Property Type="Int32" Name="DirectoryEntryId" Nullable="false" />
<Property Type="String" Name="Key" Nullable="false" />
<Property Type="String" Name="Value" Nullable="false" />
</EntityType>
<Association Name="DirectoryEntryPropertyDirectoryEntry">
<End Type="DirectoryService.DirectoryEntryProperty" Role="DirectoryEntryProperty" Multiplicity="*" />
<End Type="DirectoryService.DirectoryEntry" Role="DirectoryEntry" Multiplicity="1" />
<ReferentialConstraint>
<Principal Role="DirectoryEntry">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="DirectoryEntryProperty">
<PropertyRef Name="DirectoryEntryId" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema>
I'd like to simulate what WCF Data Services does with it's "$metadata" tag... that is, send a CSDL document that describes an existing set of objects that may (or may not) be part of an Entity Framework model. In fact, assume the EF is not part of this discussion...
I want to create a service that inspects the type of objects that it can return, generates a CSDL document and sends that to the client so that the client can code-gen those objects from the CSDL (using EDMGen should work). Once the client has generated the objects (and loaded the generated assembly), it can receive strongly-typed data from the service.
It does not seem like EDMGen can be used to generate CSDL (or EDMX) from POCOs... it can do it from a db-connection and you can generate POCOs from CSDL, but no the other way. Is there a way to this that anyone knows?
Concrete Example
Given this code:
public class DirectoryEntry
{
public int Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public ICollection<DirectoryEntryProperty> Properties { get; set; }
}
public class DirectoryEntryProperty
{
public int Id { get; set; }
public string Key { get; set; }
public string Value { get; set; }
public DirectoryEntry DirectoryEntry { get ; set; }
}
I'd like to generate this document:
<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" Namespace="DirectoryService" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:ib10="http://www.ideablade.com/edm/2010" ib10:Tag="DirectoryService">
<EntityContainer Name="DirectoryServiceContainer" annotation:LazyLoadingEnabled="true" ib10:GenerateDeveloperClasses="true" ib10:DevForceEnabled="false">
<EntitySet Name="DirectoryEntries" EntityType="DirectoryService.DirectoryEntry" />
<EntitySet Name="DirectoryEntryProperties" EntityType="DirectoryService.DirectoryEntryProperty" />
<AssociationSet Name="DirectoryEntryPropertyDirectoryEntry" Association="DirectoryService.DirectoryEntryPropertyDirectoryEntry">
<End Role="DirectoryEntryProperty" EntitySet="DirectoryEntryProperties" />
<End Role="DirectoryEntry" EntitySet="DirectoryEntries" />
</AssociationSet>
</EntityContainer>
<EntityType Name="DirectoryEntry">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Type="String" Name="Name" Nullable="false" />
<Property Type="String" Name="Type" Nullable="false" />
<NavigationProperty Name="Properties" Relationship="DirectoryService.DirectoryEntryPropertyDirectoryEntry" FromRole="DirectoryEntry" ToRole="DirectoryEntryProperty" ib10:Tag="DirectoryEntryPropertyCollectionHelper" />
</EntityType>
<EntityType Name="DirectoryEntryProperty">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<NavigationProperty Name="DirectoryEntry" Relationship="DirectoryService.DirectoryEntryPropertyDirectoryEntry" FromRole="DirectoryEntryProperty" ToRole="DirectoryEntry" />
<Property Type="Int32" Name="DirectoryEntryId" Nullable="false" />
<Property Type="String" Name="Key" Nullable="false" />
<Property Type="String" Name="Value" Nullable="false" />
</EntityType>
<Association Name="DirectoryEntryPropertyDirectoryEntry">
<End Type="DirectoryService.DirectoryEntryProperty" Role="DirectoryEntryProperty" Multiplicity="*" />
<End Type="DirectoryService.DirectoryEntry" Role="DirectoryEntry" Multiplicity="1" />
<ReferentialConstraint>
<Principal Role="DirectoryEntry">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="DirectoryEntryProperty">
<PropertyRef Name="DirectoryEntryId" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不确定以前是否已经这样做过,但是使用 T4 引擎和反射。
I'm not sure if this has been done before, but it's quite easy to accomplish what you are after using the T4 engine and reflection.
我不知道我是否正确理解你想要做什么,但是,我建议你看看 MetadataType 属性。这就是我在 RIA 服务中使用的...然后可以使用反射来查找您想要的元数据属性...
我希望这至少接近您正在寻找的:)
I don't know if I correctly understood what you're trying to do, but, I'd suggest you take a look at the MetadataType attribute. That is what I use in the RIA services... can then use reflection to look for the metadata properties you want...
I hope this is at least close to what you're looking for :)