【问题标题】:EF6 unique constraint on foreign keyEF6 对外键的唯一约束
【发布时间】:2015-12-21 00:10:55
【问题描述】:

我有以下场景:

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; }
}

如果需要,我希望插入书籍和相关作者。我有以下幼稚的代码,它会中断(几乎可以预期):

var author = _ctx.Authors.FirstOrDefault(x => x.Name == command.Author);

if (author == null)
    author = new Author { Name = command.Author };

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

_ctx.Books.Add(book);

await _ctx.SaveChangesAsync();

我看到的是,有时 FirstOrDefault 返回 null,但由于违反作者姓名的唯一索引,插入失败。是否有一些 EF 技巧可以让这种情况以简单的方式发生?我想我可以使用存储过程,但如果可能的话,我想在客户端进行。

【问题讨论】:

  • 我可以看到这会中断的唯一原因是,如果您同时添加多本书籍,并且 Author 在您查找它和将项目添加到收藏。在我看来,处理这种并发问题的最简单方法是捕获异常,将书附加到现在在 Db 中的作者,然后重新提交。
  • 1.你试过了吗? Author.Books.Add(book); ctx.SaveChangesAsync(); 2. 添加到书: public int AuthorId { get;放; } 公共虚拟作者 作者 { 获取;放; }
  • Claies 的观察是正确的......比赛正是问题所在,我正在尝试寻找解决方法。 @W92,是的……试过了。出现相同的竞争条件。问题在于作者插入。

标签: c# entity-framework-6


【解决方案1】:

在尝试了各种各样的事情之后,我做了以下事情:

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();

虽然不漂亮,但这确实可以防止作者检查和使用数据库原生功能插入之间的竞争条件。 ORM 和泄漏抽象,嗯 :)

我想我也可以把书插页放在那里,或者把整个东西做成一个sproc。如果有人想出适合这种情况的 ORM 原生方法,我会全力以赴 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多