0

我对在与 EF Code First Approach 的 1:m 关系中定义外键感到困惑。

浏览各种教程,我看到了各种方法 - 不知道有什么区别。

假设我有 2 个模型,Product其中Category1 个类别有很多产品。

public class Product
{
    public int ProductId { get; set; }
    public int CategoryId { get; set; }
    public string Name { get; set; }

    // Method 1a
    public virtual ICollection<Category> Categories {get; set; }

    // Method 1b
    public virtual List<Category> Categories {get; set; }

    // Method 1c
    public Category Category {get; set; }

    // Method 1d
    public virtual Category Category { get; set; }
}

public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }

    // Method 2a
    public List<Product> Products { get; set; }

    // Method 2b
    public ICollection<Product> Products { get; set; }

    // Method 2c
    public virtual List<Product> Products { get; set; }

    // Method 2d
    public virtual ICollection<Product> Products { get; set; }
}

public class ExampleContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
}

产品表:我认为如果我使用ICollection/并没有什么不同List,但什么时候使用 1a/1b、1c 或 1d?

类别表:我认为如果我使用ICollection/并没有什么不同List,但什么时候使用 2a、2b、2c?

4

1 回答 1

0

1a-d

至于Product-应该是1c还是1d Category1 : n

是否制作财产virtual由您决定。如果你想让它延迟加载,它应该是虚拟的。如果您总是使用急切加载(例如Include),您可以省略virtual修饰符。

2a-d

它可以是您显示的任何选项。

EF 非常满意

public (virtual) ICollection<Category> Categories {get; set; }

同样,是否要启用延迟加载取决于您。

没有必要强制ICollection<T>执行像List<T>. 您经常会看到该属性被定义为ICollection<T>,具体类型为List<T>or HashSet<T>。根据MSDN,后者提供了高性能的集合操作。您可以在实体的构造函数中初始化具体集合。

您不必同时定义两者Product.CategoryCategory.Products表达关联。这取决于您需要哪些属性的业务逻辑。

于 2013-05-28T06:50:39.533 回答