【问题标题】:How not to set DatabaseGeneratedOption.Identity for Seed entities如何不为种子实体设置 DatabaseGeneratedOption.Identity
【发布时间】:2015-10-26 22:06:58
【问题描述】:

我们将 BaseEntity 定义如下:

public abstract class BaseEntity
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Guid Id { get; set; }
        ...
}

由于 ID 是由 DB 生成的。但是,现在我们要添加种子数据。我添加了以下种子代码:

            Country c = new Country()
            {
                Id = new Guid("251D06A5-E864-4B9F-803B-00E409B0F5AB"),
                Name = "Oceania",
                RegionType = RegionTypeEnum.Region,
                ParentCountryId = worldId
            };
            AddOrUpdate(c);

在这种情况下,我的“Id”被忽略并生成了新的 Id。因此,种子总是创造新的国家。

因此我不需要数据库来为这个实体生成 Id(但我想使用 BaseEntity 作为基类)。我希望在此实体的代码中定义 Id。

您建议如何处理?

【问题讨论】:

    标签: .net entity-framework code-first


    【解决方案1】:

    AddOrUpdate 有一个重载方法,您可以在其中指定应考虑哪些属性来决定是否应添加实体。

    AddOrUpdate 方法提供了一些重载,允许您提供 Func 表达式作为第一个参数,它允许您给 EF 一个表达式来评估是否应该运行 Add 或 Update。我的最终代码如下所示:

       context.Departments.AddOrUpdate(
        d => d.Name,
        new Department() { Name = "English" },
        new Department() { Name = "Maths" },
        new Department() { Name = "French" }
    );
    

    这现在可以按预期工作,因为比较仅在 Name 列上执行。

    来源:http://www.gregpakes.co.uk/post/using-addordelete-to-seed-data-without-the-key-column

    【讨论】:

    • 也许这可以解决我的部分问题,但我仍然希望在代码中为该实体定义 Id。结束这是问题 - 如何在代码中为该实体定义 Id?
    • 如果您的列在数据库中被标识为标识列,它总是会生成一个 id,至少这是我的经验。
    • 好的,但是解决方案是什么呢?这对我来说不太好。
    • 我完全不知道。也许您应该通过禁用 Id 列的身份来开始您的 Seed 方法,并通过在方法结束时重新启用身份来结束该方法。我没有这方面的经验,但你可以检查这些 SQL 命令。您可以通过 ExecuteSqlCommand() 方法执行它们。 SET IDENTITY_INSERT tablename ONSET IDENTITY_INSERT tablename OFF注意,ON/OFF这两个词是指SQL语句能够插入自己的标识值。
    猜你喜欢
    • 1970-01-01
    • 2015-10-19
    • 2020-03-18
    • 2011-03-25
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多