【问题标题】:Mapping Relationship with Legacy Database using Entity Framework CTP5使用实体框架 CTP5 与旧数据库映射关系
【发布时间】:2011-02-22 12:56:00
【问题描述】:

我在使用 Code First / Fluent API 将两个实体与 Entity Framework CTP5 一起映射时遇到了问题。该数据库是我们公司正在切换到的另一个应用程序(Exact MAX)的旧数据库,我正在编写一个应用程序供我自己使用来管理我们仓库中的货物。没有任何内容保存到旧数据库中,其中包括本文中提到的实体。

实体是 SalesOrder,它只有一个 Address,以及 Address,它可以有多个 SalesOrder。我必须指定列名,这是问题之一。另一个是地址有两个键,一个客户 ID 和一个地址 ID,它们链接到 SalesOrder 中的匹配列。列名很可怕:表 SO_Master 中的 CUSTID_27 和 SHPCDE_27 用于 SalesOrders,表 SHIPPING_MASTER 中的 CUSTID_24 和 SHPCDE_24 用于地址。

我最终在昨晚深夜放弃了。本文中的代码行来自 SalesOrder 的映射,最后两行用于映射 SalesOrder 和 Address。我从谷歌搜索中收集的每个键都有一个映射,但我什至不确定它应该作为两个单独的通道完成。检索到的 Address 记录本身是可以的,但 SalesOrders 中的记录不是。一条检索到的 SalesOrder 记录具有有效地址,但其余 SalesOrder 记录的地址为空。

this.ToTable("SO_Master");

this.HasKey(so => so.Id);

this.Property(so => so.OrderDate).HasColumnName("ORDDTE_27");
this.Property(so => so.Id).HasColumnName("ORDNUM_27");

// Maps Customers
this
    .HasOptional(s => s.Customer)
    .WithMany(c => c.SalesOrders)
    .IsIndependent()
    .Map(m => m.MapKey(c => c.Id, "CUSTID_27"));

// Maps Address
this
    .HasOptional(s => s.Address)
    .WithMany(a => a.SalesOrders)
    .IsIndependent()
    .Map(m => m.MapKey(a => a.CustomerId, "CUSTID_27")); 

this
    .HasOptional(s => s.Address)
    .WithMany(a => a.SalesOrders)
    .IsIndependent()
    .Map(m => m.MapKey(a => a.Id, "SHPCDE_27"));

如果需要,我使用数据注释不会有任何问题。我可以改用 LINQ to SQL,但我想看看是否有使用它的解决方案。也许 EF 不是这个数据库的最佳选择,但代码分离得很好,我可以试验。我正在使用 Visual Studio Express 和 SQL Server Express 2008 R2,但找不到任何允许设计师使用的东西,所以这就是我使用 Code First 的原因。

感谢您花时间阅读这篇文章。

好的,我最终接受了 Vulgarbinary 的建议来使用数据注释,并在需要的地方使用了 ForeignKey 属性。我仍然必须使用 Fluent API 将地址映射到客户。我不确定为什么。在没有 Fluent API 映射的情况下,地址记录不断与空客户一起返回。我猜是因为我在 Address 中有两个键用于将地址与订单联系起来,但只有一个键用于客户到地址的映射。

this.HasRequired(a => a.Customer).WithMany().HasForeignKey(a => a.CustomerId);

我想我现在了解如何更好地使用 Fluent API,但我显然需要阅读更多内容。我也许可以返回并将某些属性更改回 Fluent 行,但这对于我正在处理的应用程序来说并不值得。

【问题讨论】:

    标签: c# .net entity-framework-ctp5 fluent-interface code-first


    【解决方案1】:

    SalesOrderAddress 将是 this.References(x => x.Address),您将有一个单独的字段用于 AddressID,因此您可以映射外键关联和列名。

    在地址映射上,您将拥有:

    this.WithMany(x => x.SalesOrders)

    在您的实际 POCO 中,您将需要 SalesOrder POCO 中的 FK 用于 Address 和单个 Address POCO。

    所以在 SalesOrder 类中:

    Address Address {get;set;} 
    int AddressID {get;set;}
    

    上课地址:

    List<SalesOrder> SalesOrders {get;set;}
    

    这应该为你做。

    如果我可能会问,为什么要使用 Fluent 而不是注释?通过注释一目了然地查看每行代码的效率比使用 Fluent 映射要好得多。

    【讨论】:

    • 当我开始映射到这个较旧的数据库时,我一定忘记了 EF 应该如何让您的生活更轻松。我更改为您建议的注释。少得多的工作,实体框架为我完成了大部分映射。您的回答不是解决方案,但它为我指明了正确的方向并节省了我的时间,所以我接受了。谢谢!
    • 它介绍了修复 1:M 映射需要做的事情,并指出 EF Fluent 映射工作量太大。如果我再做任何事情,我会为您编写所有代码;-) 另外,如果您发布了 POCO 和两个类的映射,我可能会编写流畅的映射更正。任何人......祝你好运!
    猜你喜欢
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 2010-10-14
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多