Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF6外键上的唯一约束_C#_Entity Framework 6 - Fatal编程技术网

C# EF6外键上的唯一约束

C# EF6外键上的唯一约束,c#,entity-framework-6,C#,Entity Framework 6,我有以下场景: public class Book { [Key] public string Isbn { get; set; } public string Title { get; set; } public int Stock { get; set; } public Author Author { get; set; } } public class Author { public int Au

我有以下场景:

public class Book {
        [Key]
        public string Isbn { get; set; }
        public string Title { get; set; }
        public int Stock { get; set; }
        public Author Author { get; set; }
}

public class Author {
    public int  AuthorId { get; set; }
    [Index(IsUnique = true)]
    [StringLength(50)]
    public string Name { get; set; }

    public ICollection<Book> Books { get; set; }
}

我看到的是,有时FirstOrDefault返回null,但插入失败,因为违反了作者名称上的唯一索引。是否有一些英孚的诡计可以让这一切以一种简单的方式发生?我想我可以使用存储过程,但如果可能的话,我想在客户端使用它。

尝试了各种方法后,我选择了以下方法:

var author = _ctx.Authors.SqlQuery(
    "with data as (select @author as [name]) " +
    "merge Authors a " +
    "using data s on s.[name] = a.[name] " +
    "when not matched by target " +
    "then insert([name]) values(s.[name]); select * from Authors where [name]=@author", new SqlParameter("author", command.Author)).Single();


var book = new Book
{
    Isbn = command.Id,
    Title = command.Title,
    Stock = command.Count,
    Author = author
};

_ctx.Books.Add(book);

await _ctx.SaveChangesAsync();
虽然不美观,但这确实防止了作者检查和使用db本机特性插入之间的竞争条件。ORMs和泄漏的抽象,呃:)


我想我也可以把书的插页放进去,或者把整个事情搞得一团糟。如果有人提出了一种ORM本机方法来满足这种情况,我洗耳恭听:)

我能看到这种情况会发生的唯一原因是,如果您同时添加多本书,并且
作者
是通过另一个过程添加的,从您查找它到将该项目添加到收藏中。在我看来,处理这类并发问题的最简单方法是捕获异常,将书附加到数据库中现在的作者,然后重新提交。1。你试过了吗?Author.Books.Add(book);ctx.SaveChangesAsync();2.添加到书中:public int AuthorId{get;set;}public virtual Author Author{get;set;}Claies的观察是正确的……种族正是问题所在,我正试图找到一个解决方法@W92,是的……试过了。同样的竞争条件也会出现。问题在作者插页上。
var author = _ctx.Authors.SqlQuery(
    "with data as (select @author as [name]) " +
    "merge Authors a " +
    "using data s on s.[name] = a.[name] " +
    "when not matched by target " +
    "then insert([name]) values(s.[name]); select * from Authors where [name]=@author", new SqlParameter("author", command.Author)).Single();


var book = new Book
{
    Isbn = command.Id,
    Title = command.Title,
    Stock = command.Count,
    Author = author
};

_ctx.Books.Add(book);

await _ctx.SaveChangesAsync();