【问题标题】:Should I use nullable types for Id's on my Entity Objects?我应该在我的实体对象上为 Id 使用可空类型吗?
【发布时间】:2010-04-05 14:53:26
【问题描述】:

我目前的设置
我有一个带有一些属性的实体对象,其中有一个int Id。为了与数据库通信,我创建了一个存储库,其中包括以下方法:

public int Add(TEntity entity)
{
    ObjectSet.AddObject(entity);
    return entity.Id;
}

(这是一个通用存储库,要求TEntityclass,并且它实现了IEntity,这只是一个带有int Id 属性的接口。)

我的问题:
现在,当我想创建一个新实体以添加到存储库时,我需要给它一个 id。但是,这不允许 EF 自动为我生成 id,因为它已经有一个值。

可能的解决方案:
我只能想到这两种可能。

  1. 使Id 属性可以为空
  2. EntryInputModel 传递给存储库,然后在那里进行映射。
    目前我在我的控制器中绑定到EntryInputModel,并使用AutoMapper 将其映射到Entry。如果我需要改变这一点,我还需要重新考虑我的项目中的依赖关系,因为 ...InputModel...ViewModel 类目前仅适用于我的 Web 应用程序。

哪个更可取?有更多的方法来解决这个问题吗?

【问题讨论】:

    标签: asp.net-mvc repository nullable entity-framework-4


    【解决方案1】:

    如果您使用 SQL Server 作为后端,我推荐的解决方案是在数据库中将 ID 列设为 INT IDENTITY,并在实体对象中设为不可为空的列。

    添加新实体时,为 ID 分配任意值,例如 -1 或其他值,或者根本没有值,甚至。插入新实体时,SQL Server 会自动生成实际 ID (

    EntityContext.AddToEntities(newEntity);
    EntityContext.SaveChanges();
    

    它会自动返回给 EF,因此您可以在插入后立即使用它:

    int newEntityID = newEntity.ID;
    

    像魅力一样工作 - 至少在我的测试应用中:-)

    【讨论】:

    • 我还没有真正创建数据库。如何在存储库上的 Add() 方法的单元测试中反映此行为?
    • @Tomas:如果你需要模拟这个,你需要在调用 .SaveChanges() 时将标识字段设置为有效值
    • @marc:正如您在上面的 Add 方法中看到的,我实际上没有调用 SaveChanges() 。这是否意味着无法从中取回新的id?
    • @Tomas:如果您使用服务器生成的 ID(IDENTITY 字段),则只有在实际插入数据时才会生成这些 ID,例如当你打电话给SaveChanges()
    • @marc:我认为问题实际上是我自己很愚蠢。我应该做的是将实体传递到存储库并添加它,然后在我的 UnitOfWork(在本例中是 ObjectContext 的包装器)上调用 SaveChanges,然后在我需要的地方使用实体的 id 属性。因为它不在数据库中,所以当我保存它时,EF(或者更确切地说是 SQL Server)将分配新的 id 而不管它的当前 ID。对?换句话说,在我的测试中,我只需要确保 AddObject 方法是从 Add 调用的,并且 SaveChanges 可以正确传播。我需要在控制器中测试其他任何东西吗?
    【解决方案2】:

    您可以生成不是由数据存储/EF 生成的唯一 ID,允许您在将对象传递到 EF 之前定义它们...(想想 Guid)

    【讨论】:

    • 但是,我想使用ints 作为 id,以便能够在 url 中使用它们而不会失去太多可读性。
    猜你喜欢
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 2019-05-29
    • 1970-01-01
    • 2021-03-03
    相关资源
    最近更新 更多