在Entity Framework Core中使用“Attach”作为Upsert

时间:2018-02-04 21:13:35

标签: c# ssms entity-framework-core database-first

根据oneunicorn

  

DbSet.Attach将图表中的所有实体置于Unchanged状态。但是,如果实体具有存储生成的密钥(例如,标识列)并且未设置密钥值,则实体将处于已添加状态。

我遇到“商店生成密钥”部分的问题。我的数据库是在SMSS中创建的,我的表有一个uniqueidentifier类型的Id列,而不是null。这是主要的关键。但是,如何判断SMSS应该是存储生成的呢?当我运行导入时C#会发现这个吗? (特别是,如果可能的话,我想对内存数据库进行测试。)

2 个答案:

答案 0 :(得分:1)

使用alter table SQL语句设置列的默认值:

alter table myTable alter column myIdColumn default newid()

在c#端,装饰你的EF类,表明该列的值是自动生成的:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
Guid myIdColumn { get; set; }

答案 1 :(得分:1)

当您在其中一个表中插入行时,数据库的Id列为  表配置为自动生成新的guid?使用newid()或newsequentialid()?后者是优选的,因为它更好地指数。非顺序guid会影响插入重表中的性能。

以下是具有商店生成的Id列的表定义的示例。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

/*The Main Function Start*/
void main(int argc, char *argv[])
{
    /*Storing The Process Id*/
    pid_t pid;
    int j;
    int status = 0;


    /*process of forking*/

    if (argc == 1){
        fprintf(stderr,"Usage: ./hw1 <starting value>\n");
    }
    int n = atoi(argv[1]);
    pid=fork();
    if (pid == -1){
        printf("Error in forking....\n");
        exit(0);
    }
    /*Child process*/
    if (pid == 0)
    {
        printf("Child PID: %d\n",getpid());

        while (n != 1){
            printf("%d ",n);
            if (n % 2 == 0){
                n = n/2;
            }
            else {
                n = 3*n + 1;
            }

        }
        printf("1\n");
    }
    else{
        printf("Parent PID: %d\n",getpid());
        /*Waiting for the child to finish*/
        wait(0);
    }
    exit(0);
}

然后将如此指定EF模型......

CREATE TABLE [dbo].[MyTable] (
    [Id] [uniqueidentifier] NOT NULL PRIMARY KEY CLUSTERED CONSTRAINT [PK_MyTable_Id] DEFAULT (newsequentialid()) 
)