临时关闭身份 - Entity Framework 4.1 Code First
当我将数据导入具有不同 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
SqlQuery
返回一个IEnumerable
,并且在枚举它之前不会执行 sql 查询。如果您在语句末尾添加.ToList()
,您将收到一个异常,指出语法不正确。当 EF 尝试将结果映射到Observation
时,您还会遇到问题。我终于能够使用以下命令运行它:
这导致了我无法解决的最终问题。由于
Id
被标记为由数据库生成,因此 EF 不会在INSERT
语句中包含其值。如果您可以找到一种方法在运行时更改
Id
上的DatabaseGeneratedOption
值,则可以使用上下文添加实体。不幸的是,我不知道如何执行此操作,插入具有指定Id
的行的唯一方法是使用底层连接并执行所需的 sql。SqlQuery<T>
returns anIEnumerable
, 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 anObservation
.I was finally able to get this to run using the following:
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 theINSERT
statement.If you can find a way to alter the
DatabaseGeneratedOption
value onId
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 specifiedId
was to use the underlying connection and execute the sql needed.感谢您的输入,我通过回到基础并从数据库需求中删除客户需求来解决这个问题。最终得到一列来存储客户需求(例如实例 + 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 :)