【问题标题】:Fluent API Mapping流畅的 API 映射
【发布时间】:2012-11-29 21:20:48
【问题描述】:

我有一个包含三个结构如下表的数据库:

Table 1: Product
Columns: ProductID, PK
         SKU,       PK
         Name

Table 2: ProductImages
Columns: ImageID    PK
         SKU

Table 3: Images
Columns: ImageID    PK
         ImageContent

暂时忽略表 ProductImages 看起来是多对多关系,除了唯一 PK 约束强制为一对一,因此是不必要的一对多对-一张表(它是一个现有的数据库)。

我想要以下POCO实体类:

public class Product
{
    public int ProductId { get; set; }
    public string SKU { get; set; }
    public virtual Image Image { get; set; }
}

假设Image 也是我的实体模型中的一个实体。

我使用Entity Framework 5.0 和代码优先和Fluent API,我正在发疯试图弄清楚如何编写ProductMap 类(派生自EntityTypeConfiguration<Product>)。特别是关系映射。

呈现的 SQL 应该类似于以下实体框架的版本:

select p.SKU, p.Name, p.ProductID, I.ImageID, I.ImageContent
from Products p
inner join ProductImages si on p.SKU = si.SKU
inner join Images i on i.ImageId = si.ImageId

任何人可以提供的任何帮助都会得到衷心的感谢。

【问题讨论】:

  • SKU 不应该是 ProductImages 的主键吗?如果是这种情况,那么您似乎需要一组产品图像,其中包含一组图像,包含在您的产品类中。
  • 除非您愿意通过告诉 EF Product 只有 SKU 作为主键来欺骗 EF,否则您不会这样做。 (多对多映射是可能的)。但这可能会导致异常,因为实际上 SKU 在 Product 中可能不是唯一的。

标签: entity-framework entity-framework-5 fluent-interface


【解决方案1】:

在我开始使用Entity Framework Power Tools之前,我遇到了同样的问题

使用它,您可以生成清晰的实体,例如业务对象和映射类。 帮助我创建了惊人的数据访问层的好文章:Reverse Engineer Code First

我认为映射应该是这样的:

public class ProductMap : EntityTypeConfiguration<Product>
{
    public ProductMap ()
    {
        // Primary Key
        this.HasKey(t => t.ProductId);

        // Properties
        this.Property(t => t.Name)
            .IsRequired()
            .HasMaxLength(256);

        // Table & Column Mappings
        this.ToTable("Product");
        this.Property(t => t.ProductId).HasColumnName("ProductID");
        this.Property(t => t.Name).HasColumnName("Name");

        // Relationships
        this.HasMany(t => t.Products)
            .WithMany(t => t.Images)
            .Map(m =>
            {
                m.ToTable("ProductImages");
                m.MapLeftKey("ProductID");
                m.MapRightKey("ImageID");
            });
        }
    }

【讨论】:

  • 感谢您的回复。我已经用过这个工具了。两个问题是 Products.SKU - > ProductImages.SKU 在数据库中不存在(因此无法逆向工程出来),第二个问题是即使可以,映射的 POCO 也会是 Products.ProductImages[0]。图片。我需要将关系展平为 Products.Image。
【解决方案2】:

我想通了。数据库结构和我的实体模型之间存在逻辑脱节。

productImages 表支持 *-1 映射,因此 Products POCO 类需要有一个 ProductImage 集合。那么实体需要进行如下配置:

public class ProductImagesMap : EntityTypeConfiguration<ProductImage>
{
        //Other field and key configuration...

        this.HasRequired(t=>t.Image).WithRequiredDependent();

        this.HasRequired(t => t.Product)
        .WithMany(t => t.ProductImage)
        .HasForeignKey(d => d.SKU);
}

public class ProductImage
{
    public int ImageId { get; set; }
    public string SKU{ get; set; }
    public virtual Image Image { get; set; }
    public virtual Product Product { get; set; }
}

public class Product
{
    public Product()
    {
        this.Features = new List<Feature>();
    }

    public int ProductId { get; set; }
    public string Name { get; set; }
    public string SKU{ get; set; }
    public virtual Brand Brand { get; set; }
    public virtual ICollection<ProductImage> ProductImages { get; set; }
}

我努力尝试在 ProductMap 类中配置这种关系(作为父/母表中的产品),直到从 ProductImages 类中配置它才起作用,所以我的两个未解决的问题是:

1) 哪些规则决定了哪个实体驱动关系配置?

2) 有没有办法可以将 Products POCO 类配置为具有 ICollection Images 属性并完全绕过 ProductImage 实体,因为 ProductImage 仅用作产品和图像之间的链接表?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2010-11-22
    • 2011-11-15
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多