对于我的API,我正在使用Entity Framework Core进行代码优先迁移。我创建了一些工作正常的关系。现在,我添加了另一个关系(一对多),突然我被这个错误拍到耳边:
Cannot insert explicit value for identity column in table 'Companies' when IDENTITY_INSERT is set to OFF."
在场外,我肯定做错了什么,但我只是不知道什么。我遇到了更多类似这样的问题,答案是“将IDENTITY_INSERT设置为ON”,但这对我不起作用,因为EF正在处理一切。
可以属于某个组的“我的公司”类别:
public class Company
{
// Primary key
public int Id { get; set; }
// The optional Id of a Group
public int? GroupID { get; set; }
...
}
还有Group类:
public class Group
{
// Primary key
public int Id { get; set; }
// Name of the Group
public string Name { get; set; }
// List of Companies in this group
public IEnumerable<Company> Companies { get; set; }
}
用于处理POST的代码:
// POST api/groups
[HttpPost]
public async Task<IActionResult> Post([FromBody] Group group)
{
try
{
if (ModelState.IsValid)
{
_context.Groups.Add(group);
await _context.SaveChangesAsync();
return CreatedAtRoute("GetGroup", new { id = group.Id }, group);
}
return BadRequest(ModelState);
}
catch (Exception e)
{
return BadRequest($"Unable to create: {e.Message}");
}
}
在我的数据库中,所有列,索引和键均按预期方式创建,就像我在API中获得的其他一对多关系一样。但是这个特定的案例似乎最终陷入了痛苦之中……
我要添加到数据库中的类:
答案 0 :(得分:1)
问题在于,EF没有任何提示,可以知道是否正在显式插入Company
(在Group
关系下),或者是否应该使用数据库中预先存在的那个。
由于实例实例已与DbContext
断开连接,因此在EF尝试生成其SQL命令时,没有迹象表明它们在数据库中是否存在。
这里没有简单的方法,至少在我使用EF Core玩游戏时没有。
您应该:
ID
而不是导航属性,以便尽可能避免使用此代码,或者; Company
之前,更改代码以获取相关数据(例如:获取Group
并将其附加到Group
)。例如,
var companyDB = await context.Companies.SingleOrDefaultAsync(c => c.Id == group.Company.Id);
group.Company = companyDB;
context.Groups.Add(group);
await context.SaveChangesAsync();
是的,您要两次访问数据库。这就是为什么我建议使用第一种方法的原因,因此您可以避免这种提取,而只需将Group
实体直接保存到DB中即可。
但是,这并不禁止您向视图发送Company
导航实例。只需创建一些与数据库相关的与实体相关的类,以便您可以使用此实体类型加载/保存数据,并创建一个Dto
对象,该对象将在需要时用作端点输入/输出。
可以使用AutoMapper,手动linq或其他方法将彼此绑定在一起。
答案 1 :(得分:0)
这是因为您要在设置为标识(自动递增)的列中传递一些值。
我认为您要插入的Group
实体具有要尝试将其值插入到公司表中的ID的公司作为子记录。并引发错误。
答案 2 :(得分:0)
在尝试保存与现有实体(属性library(shiny)
library(shinyjs)
# The tab need to be closed programmatically; here is a quick solution
# https://github.com/daattali/advanced-shiny/blob/master/close-window/app.R
jscode <- "shinyjs.closeWindow = function() { window.close(); }"
# App One
appOne <- list(
ui = fluidPage(
useShinyjs(),
extendShinyjs(text = jscode, functions = c("closeWindow")),
fluidRow(
column(3),
mainPanel(h2("Welcome to the load page"),
plotOutput("plot"),
actionButton("quit", "QUIT", class = "btn-warning")))
),
server = function(input, output, session) {
output$plot <- renderPlot({
with(cars, hist(dist, breaks = 10))
})
observeEvent(input$quit, { js$closeWindow(); stopApp("appRoute") })
}
)
# App TWO
appTwo <- list(
ui = fluidPage(
useShinyjs(),
extendShinyjs(text = jscode, functions = c("closeWindow")),
fluidRow(
column(3),
mainPanel(h2("Welcome to appTwo"),
plotOutput("plot"),
actionButton("quit", "QUIT", class = "btn-warning")))
),
server = function(input, output, session) {
output$plot <- renderPlot({
plot(cars)
})
observeEvent(input$quit, { js$closeWindow(); stopApp("appRoute") })
}
)
# Router
appRoute <- list(
ui = fluidPage(
useShinyjs(),
extendShinyjs(text = jscode, functions = c("closeWindow")),
fluidRow(
column(3),
mainPanel(h2("Welcome to Selector"),
actionButton("appOne", "AppOne"),
actionButton("appTwo", "AppTwo"),
actionButton("appEnd", "END", class = "btn-danger")
))
),
server = function(input, output, session) {
observeEvent(input$appOne, { js$closeWindow(); stopApp("appOne") })
observeEvent(input$appTwo, { js$closeWindow(); stopApp("appTwo") })
observeEvent(input$appEnd, { js$closeWindow(); stopApp("appEnd") })
}
)
# Main loop
route <- "appRoute"
while (TRUE) {
app <- switch(
route,
appRoute = shinyApp(appRoute$ui, appRoute$server),
appOne = shinyApp(appOne$ui, appOne$server),
appTwo = shinyApp(appTwo$ui, appTwo$server),
appEnd = "END"
)
if (is.null(app)) { # not matched
warning("Unknown route ", route)
route <- "appRoute"
next
} else if (is.character(app)) { # final end
message("Ending")
break
}
# Execute a new app and retrieve return code
route <- print(app)
message("New route ", route)
# browser()
}
具有多对一关系并指向{{1}的实体(例如Cat
)时,我遇到了类似的问题})。除了a)在保存实体(Owner
)之前从数据库获取关系(Person),以及b)向实体(Person
)添加另一个属性(Cat
),我发现了我认为是最好的解决方案:c)仅坚持“导航”属性(不要创建额外的int PersonId
属性),并且在需要引用时,使用Cat
答案 3 :(得分:0)
Entity Framework 由于某种原因丢失了跟踪,Entity Framework 需要为已经存在的实体重新建立跟踪。
您可以通过以下方式获取实体跟踪的状态:
var entityTrackingState = _context.Entry(entity).State;
您可以通过以下方式强制实体框架对现有实体进行跟踪:
_context.Entry(untrackedEntity).State = EntityState.Unchanged;
哪里
_context
是一个实体框架 DbContext。
强制跟踪解决了我的问题,但确实应该在实体框架丢失跟踪的地方进行调试。