1

问题是“一个作者可能没有或有很多书,但一本书绝不是由两个或多个作者写的。”

public Author(Document cpf, string name, DateTime birthdate)
        {
            Cpf = cpf;
            Name = name;
            Birthdate = birthdate;
        }

        public Document Cpf { get; private set; }
        public string Name { get; private set; }
        public DateTime Birthdate { get; private set; }
        // EF Relation
        public Book Book { get; private set; }
        public ICollection<Book> Books { get; private set; }

        protected Author() { }

// 0 : N => Author : Books
            builder.HasMany(c => c.Books)
                .WithOne(b => b.Author)
                .HasForeignKey(b => b.AuthorId);
public Book(Guid categoryId, Guid authorId, string title, DateTime releaseDate, BookIdentificator isbn)
        {
            CategoryId = categoryId;
            AuthorId = authorId;
            Title = title;
            ReleaseDate = releaseDate;
            Isbn = isbn;
        }

        public Guid CategoryId { get; private set; }
        public Guid AuthorId { get; private set; }
        public string Title { get; private set; }
        public DateTime ReleaseDate { get; private set; }
        public BookIdentificator Isbn { get; private set; }
        public Category Category { get; private set; }
        public Author Author { get; private set; }
            // 1 : 1 => Books : Author
            builder.HasOne(c => c.Author)
                   .WithOne(b => b.Book)
                   .HasForeignKey(b => b.AuthorId);

错误:无法将 lambda 表达式转换为类型“字符串”,因为它不是委托类型 BookManager.Catalog.Data

4

2 回答 2

2

这是一个很难帮助您解决的问题,因为您没有发布您的AuthorBook课程的完整示例,只有片段并且这些片段还不够完整。

您的特定错误已被讨论:

无法将 lambda 表达式转换为类型“字符串”,因为它不是委托类型

这是因为编译器期望您使用QueryTypeBuilder.HasOne 方法的重载之一,并且发现没有匹配它默认为HasOne(string, string). 您应该使用扩展方法来简化对流畅配置的访问。

添加 using 语句:

using System.Linq; 
using System.Data.Entity;

这只是您的问题的开始,接下来是Author具有以下两个属性的问题:

// EF Relation
public Book Book { get; private set; }
public ICollection<Book> Books { get; private set; }

在这里,您是说每个作者都有一本特定的书一组书。在不了解应用程序的其余部分的情况下,这可能是有效的,也许单本书参考是作者的传记?还是他们的第一本书?无论哪种方式,如果您希望存在这样的关系,您将需要使用流利的表示法来专门描述用于这两种关系的端点。

我是否可以建议您只需要类Books上的属性Author

// EF Relation
public virtual ICollection<Book> Books { get; set; } = new HashSet<Book>();

然后你的流利符号仍然需要以下调整:

作者

这里没有变化,这个是有效的,使用更长的变量名来帮助解释关系。

您不必linq 语句中的变量名减少为单个字符,但如果这样做,请使用概念变量名或类型的第一个字符,以便更容易阅读和查看代码的预期。

// 0 : N => Author : Books
builder.HasMany(author => a.Books)
       .WithOne(book => book.Author)
       .HasForeignKey(book => book.AuthorId);

在原始代码中,OP 错误地指出该Book:Author比率是1:1,而实际上它是Many:1

// N : 1 => Books : Author
builder.HasOne(book => book.Author)
       .WithMany(author => author.Books)
       .HasForeignKey(book => book.AuthorId);

注意:虽然您可以在正向或反向逻辑中指定每个关系,但只需通过流利表示法指定每个关系一次。

  • 只需要定义上述配置之一,它们都描述了相同的链接。

使用类上的属性表示法可以实现相同的配置Book

[ForeignKey(nameof(AuthorId))]
public virtual Author Author { get; set; }

关于我的代码风格的最后一点,我建议将所有导航属性声明为虚拟,以促进延迟加载和更改跟踪优化。

此外,所有集合属性都应该自动初始化,new HashSet<T>()以减少您必须编写的代码以在运行时创建对象并支持链式数据操作。

于 2019-12-22T21:25:46.253 回答
0

看不到您的代码有任何问题。也许你只是错过了一个using声明?无法将 lambda 表达式转换为类型“字符串”,因为它不是委托类型

于 2019-12-22T20:25:04.923 回答