临时关闭身份 - Entity Framework 4.1 Code First

发布于 2024-12-11 02:56:47 字数 1372 浏览 0 评论 0原文

当我将数据导入具有不同 ID 的数据库时,我遇到了再次创建 ID 的问题。所有数据导入正确,只是身份(ID 列)需要是导入的内容。

在这个模型中我们有两个键; ID 和身份。身份基本上是来自其他数据源的唯一实例名称,因此这将创建一个唯一的组合。

这一切都是通过来自 DbContext 类的 DatabaseContext 上的 OnModelCreating 来设置的:

        modelBuilder.Entity<Observation>().HasKey(m => new {m.Instance, m.Id});
        modelBuilder.Entity<Observation>().Property(m => m.Id).HasDatabaseGeneratedOption(
            DatabaseGeneratedOption.Identity);

该类如下所示:

public class Observation
{
    public string Instance { get; set; }
    public int Id { get; set; }
    ...
}

数据库上下文仅在使用 Ninject 的 ASP.Net MVC 3 应用程序中创建一次。

我尝试使用 SQL 命令在添加新条目时关闭身份,但没有成功:

    public void SetIdentiyObservation(bool isOn)
    {
        var state = isOn ? "ON" : "OFF";
        _context.Database.SqlQuery<Observation>("SET IDENTITY_INSERT Observation @state", new SqlParameter("state", state));
    }

创建的表结构在 MSSQL 中看起来像这样:

CREATE TABLE [dbo].[Observations](
[Instance] [nvarchar](128) NOT NULL,
[Id] [int] IDENTITY(1,1) NOT NULL,
    ...
PRIMARY KEY CLUSTERED 
(
[Instance] ASC,
[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

对此的任何帮助表示赞赏:)

I'm having a issue with ID being created again when I import data into the database that has a different ID. All the data imports correctly, its just that the identity (ID column) needs to be what the import is.

We have two keys in this model; ID and Identity. Identity is basically a unique instance name from the other datasource, so this will create an unique combination.

This is all set via the OnModelCreating on the DatabaseContext which is from class DbContext:

        modelBuilder.Entity<Observation>().HasKey(m => new {m.Instance, m.Id});
        modelBuilder.Entity<Observation>().Property(m => m.Id).HasDatabaseGeneratedOption(
            DatabaseGeneratedOption.Identity);

The class looks like this:

public class Observation
{
    public string Instance { get; set; }
    public int Id { get; set; }
    ...
}

The database context is only created once in this ASP.Net MVC 3 Application with Ninject.

I tried using a SQL command to set identity off while adding a new entry, but with no success:

    public void SetIdentiyObservation(bool isOn)
    {
        var state = isOn ? "ON" : "OFF";
        _context.Database.SqlQuery<Observation>("SET IDENTITY_INSERT Observation @state", new SqlParameter("state", state));
    }

The created table structure looks like this in MSSQL:

CREATE TABLE [dbo].[Observations](
[Instance] [nvarchar](128) NOT NULL,
[Id] [int] IDENTITY(1,1) NOT NULL,
    ...
PRIMARY KEY CLUSTERED 
(
[Instance] ASC,
[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Any help on this is appreciated :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

贱贱哒 2024-12-18 02:56:47

SqlQuery 返回一个 IEnumerable,并且在枚举它之前不会执行 sql 查询。如果您在语句末尾添加 .ToList() ,您将收到一个异常,指出语法不正确。当 EF 尝试将结果映射到 Observation 时,您还会遇到问题。

我终于能够使用以下命令运行它:

_context.Database.SqlQuery<object>("SET IDENTITY_INSERT Observation " + (isOn ? "ON" : "OFF")).ToList();

这导致了我无法解决的最终问题。由于 Id 被标记为由数据库生成,因此 EF 不会在 INSERT 语句中包含其值。

如果您可以找到一种方法在运行时更改 Id 上的 DatabaseGeneratedOption 值,则可以使用上下文添加实体。不幸的是,我不知道如何执行此操作,插入具有指定 Id 的行的唯一方法是使用底层连接并执行所需的 sql。

SqlQuery<T> returns an IEnumerable, and the sql query is not executed until you enumerate it. If you add a .ToList() at the end of the statement, you'll get an exception saying that the syntax is incorrect. You'll also run into problems when EF tries to map the result into an Observation.

I was finally able to get this to run using the following:

_context.Database.SqlQuery<object>("SET IDENTITY_INSERT Observation " + (isOn ? "ON" : "OFF")).ToList();

Which led to a final problem that I couldn't resolve. Because Id is marked as generated by the database, EF does not include its value in the INSERT statement.

If you can find a way to alter the DatabaseGeneratedOption value on Id at runtime, you could add the entity using your context. Unfortunately, I don't know how to do this, and the only way I could insert a row with a specified Id was to use the underlying connection and execute the sql needed.

她说她爱他 2024-12-18 02:56:47

感谢您的输入,我通过回到基础并从数据库需求中删除客户需求来解决这个问题。最终得到一列来存储客户需求(例如实例 + id),然后数据库可以通过内部 ID 实现自己的生活:)

Thanks for the input adrift, I solved this by going back to basic and removing the customer needs from the database needs. Ended up with a column to store the customer requirements for instance + id and then the database can live its own life with internal ID :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文