gpt4 book ai didi

c# - EntityFramework DatabaseGenerated.Identity 和 AutoMapper == null ID 键

转载 作者:行者123 更新时间:2023-12-03 00:34:00 24 4
gpt4 key购买 nike

我正在将 EF 和 AutoMapper 与 Azure 表存储模拟结合使用。

我有两种类型,Fragment(可序列化DTO)和FragmentEntity(EF持久化DO)。我使用 AutoMapper 从 DTO 映射到 DO,以便在 PUT 调用上持久化,反之亦然在 GET 调用上。

问题是我对 EF 和 AutoMapper 都缺乏经验。我已将 FragmentEntity 类(根据我能找到的文档)配置为在数据库中生成 Fragment 的 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 值为 null(因为我已将 ID 属性定义为可选)。

 public void PutFagment(Fragment fragment)
{
var fragmentEntity = Mapper.Map<Fragment, FragmentEntity>(fragment);
_fragmentContext.Add(fragmentEntity);
}

[DataMember]
public virtual int? Id { get; set; }

我不确定将其定义为可选是否是明智之举;我这样做是因为如果它不是可选的,则值默认为零,然后自动映射器映射到目标 FragmentEntity,随后数据库中的所有键最终为零(显然是错误的)。

正如您所期望的那样,我还将 FragmentEntity Id 设为可选,以避免在应用程序代码中设置值,我希望如果它为 null,则可能会生成数据库,但这似乎不会发生。

<Fragment><Id i:nil="true"/><Name>Drei</Name><Type>3</Type></Fragment>

我的问题:

  1. 我认为在两个类中使 Id 为可选的决定是不正确的,我假设有一些 AutoMapper 配置可以适本地处理这种情况,并且两者都可以保持非可选。
  2. 我不确定为什么 DatabaseGenerate 属性没有生效。

最佳答案

因此,事实证明,开发人员负责使用 Azure 表存储来生成其唯一的行键。这是针对扩展 TableServiceEntityFragmentEntity 完成的。也就是说,提供商不支持数据库 key 生成,开发人员必须拥有它。

这意味着:

  1. 您必须拥有 ID 生成代码。
  2. 您无需在 TableServiceEntity 中定义 Id 属性,只需在 AutoMapper 配置中提供双向的合理映射即可。

ID 不应由客户端指定(这是服务器的责任)。因此,从 DTO 到持久 DO 的映射会使用新生成的 Guid 覆盖默认设置的任何值(请参阅下面的代码)。

Mapper.Configuration.CreateMap<Fragment, FragmentEntity>()
.ForMember(dest => dest.RowKey,
expression => expression.ResolveUsing(source => Guid.NewGuid().ToString()))
// NB: you are also required to provide a partition key for TableServiceEntities
.ForMember(dest => dest.PartitionKey,
opt => opt.ResolveUsing(source => PartitionKeyConstants.LocalPartitionKey));

然后,必须配置从FragmentEntityFragment的另一个方向的映射,将DTO的Id属性设置为的RowKey值FragmentEntity.

Mapper.Configuration.CreateMap<FragmentEntity, Fragment>()
.ForMember(dest => dest.Id,
expression => expression.ResolveUsing(source => source.RowKey));

我的映射代码在 Global.asax.cs 中注册以处理映射注册。我将在某个时候将其移至 IoC 容器中。

由于此更改,我不再在 FragmentEntity 中定义 ID,并且 Fragment 类中定义的 Id 属性不再是可选的。

[DataMember]
public virtual Guid Id { get; set; }

注意:我使用 Guid 是因为生成唯一的 Guid 值比跟踪 int 键和增量更容易。这也意味着我在检查下一个 int 键值时不会引入数据库锁瓶颈。

关于c# - EntityFramework DatabaseGenerated.Identity 和 AutoMapper == null ID 键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13639138/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com