我使用EF和AutoMapper与Azure表存储模拟。EntityFramework DatabaseGenerated.Identity和AutoMapper == null ID键
我有两种类型,Fragment(可序列化DTO)和FragmentEntity(EF持久DO)。我使用AutoMapper从DTO映射到DO,以便在PUT调用上持久化,反之亦然。
问题是我对EF和AutoMapper都没有经验。我已经将FragmentEntity类(根据我可以找到的文档)配置为在数据库中生成片段的Id(请参见下文)。
实体ID的定义:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int? Id { get; set; }
在运行HTTP客户端与所述新的内容(片段)一个REST PUT调用。这是通过WCF接收并序列化为片段,如下所示。
[OperationContract]
[WebInvoke(UriTemplate = "/Fragments", Method = "PUT")]
void PutFagment(Fragment fragment);
在调试过程中,如果我跨越代码接收到的ID值为空(因为我已将ID属性定义为可选)。
public void PutFagment(Fragment fragment)
{
var fragmentEntity = Mapper.Map<Fragment, FragmentEntity>(fragment);
_fragmentContext.Add(fragmentEntity);
}
[DataMember]
public virtual int? Id { get; set; }
我不确定是否将其定义为可选是明智之举;我这样做是因为如果它不是可选的,那么默认值为零,然后automapper映射到目标FragmentEntity,随后所有的键在数据库中最终为零(明显错误)。
正如你所料,我也已经使FragmentEntity Id可选,以避免在应用程序代码中设置一个值,我的希望是如果它为null数据库代可能发生但是这似乎并没有发生。
<Fragment><Id i:nil="true"/><Name>Drei</Name><Type>3</Type></Fragment>
我的问题:
- 我认为决定把ID可选在这两个类是不正确的,我认为有一些AutoMapper配置,这将适当地处理这种情况,并且既可以保持非可选的。
- 我不确定为什么DatabaseGenerated属性没有生效。
1.同意,它可能不应该是可选的。您可以在AutoMapper配置中使用条件选项,以便在零映射时不映射它,但我认为这不是您真正的问题。 2.这是你真正的问题,但不幸的是,我没有EF能够提供帮助的经验。你可能在这里找到一些有趣的东西? http://stackoverflow.com/questions/5124911/using-database-generated-guid-and-datetime-with-ef4 – Mightymuke
感谢您的链接,它给了我一个有趣的想法。也许是因为azure表存储不是关系数据库,它不提供数据库密钥生成。这也可以解释为什么当它在表中有两个项目(0或null)时它不会引发异常......也许我必须获得该代码的所有权。 – Syntax
如果您试图保留重复的RowKey值,它实际上会抛出异常,但很明显,因为RowKey用于唯一性,所以用户定义的任何键都不会被认可,这意味着Azure表存储不支持[Key]和[DatabaseGeneratedOption]属性。 – Syntax