简体   繁体   English

实体框架代码优先:在具有不同连接列的实体中展平组合

[英]Entity Framework Code First : flatten composition in entity with different join column

I have an issue working with EntityFramework using Code First configuration. 我使用Code First配置使用EntityFramework时遇到问题。 I have two tables : 我有两张桌子:

+---------------+        +-------------+
|  T_CONTRACTS  |        |  T_PERSONS  |
|---------------|        |-------------|
|CONTRACT_ID    |        |PERSON_ID    |
|CUSTOMER_ID    |        |NAME         |
+---------------+        +-------------+

I want to have a single EF entity : 我想拥有一个EF实体:

public class Contract
{
    public int ContractId { get; set; }
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }

}

Now, I would like to map my two tables on my entity. 现在,我想在我的实体上映射我的两个表。 I order to do that, I used EntityTypeConfiguration. 为了做到这一点,我使用了EntityTypeConfiguration。

public class ContractConfiguration : EntityTypeConfiguration<Contract>
{
    public ContractConfiguration()
    {
        ToTable("T_CONTRACTS", "ASSUROL"); //table and schema ALWAYS in uppercase
        HasKey(c => c.ContractId);
        Property(c => c.ContractId).HasColumnName("CONTRACT_ID").IsRequired();
        Property(c => c.CustomerId).HasColumnName("CUSTOMER_ID").IsRequired();

        // TODO : WIP, no idea of what i am doing
        HasRequired(c => c.CustomerName).WithRequiredPrincipal().Map( ca => {
            ca.MapKey("PERSON_ID");
            ca.ToTable("T_PERSONS", "ASSUROL");

            //Property(c => c.CustomerName).HasColumnName("NAME");
        });

    }
}

And here come the crap, i dont know how to achieve the mapping. 这里有废话,我不知道如何实现映射。

-How to map a entity fields to two tables ? - 如何将实体字段映射到两个表?

-How to join two tables with different column name for the foreign key (Here CUSTOMER_ID and PERSON_ID) ? - 如何为外键连接两个具有不同列名的表(此处为CUSTOMER_ID和PERSON_ID)?

Thanks a lot, 非常感谢,

PS : I know we can do this by making two entities with data annotation. PS:我知道我们可以通过制作带有数据注释的两个实体来实现这一点。 I would like to avoid data annotation (because of separation of concern) and I would like to keep a single entity. 我想避免数据注释(因为关注点分离),我想保留一个实体。

First, your models don't look right. 首先,您的模型看起来不正确。 You (probably) want something like: 你(可能)想要这样的东西:

public class Contract
{
    public int ContractId { get; set; }
    public int PersonId { get; set; }
    public Person Customer { get; set; }  // Use a navigation property to relate
}

public class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    public ICollection<Contract> Contracts { get; set; }  // A person can have many contracts, no?
}

Now you can alter your fluent code to: 现在您可以将您的流畅代码更改为:

public class ContractConfiguration : EntityTypeConfiguration<Contract>
{
    public ContractConfiguration()
    {
        ToTable("T_CONTRACTS", "ASSUROL"); //table and schema ALWAYS in uppercase
        HasKey(c => c.ContractId);  // Redundant since ContractId is key via convention
        Property(c => c.ContractId).HasColumnName("CONTRACT_ID").IsRequired();
        Property(c => c.PersonId).HasColumnName("CUSTOMER_ID").IsRequired();

        // Configure the relationship although EF should pick this up by convention as well...
        HasRequired(c => c.Customer).WithMany(p => p.Contracts);

    }
}

Now you can pretty easily compose a query to "flatten" the relationship: 现在,您可以轻松地撰写查询以“扁平化”关系:

context.Contracts.Select(c => new {
       c.ContractId,
       CustomerId = c.PersonId,
       CustomerName = c.Person.Name }).ToList();

EDIT: Upon a reread, I see that what you might be after is table splitting, although the first approach is better IMO because it seems like you are trying to build a ViewModel into your entity model which is not the intent of table splitting. 编辑:重读后,我看到你可能会遇到的是表拆分,虽然第一种方法是更好的IMO,因为看起来你正试图在你的实体模型中构建一个ViewModel,这不是表拆分的意图。 IAC, if you want it the fluent code would look similar to: IAC,如果你想要它,流畅的代码看起来类似于:

modelBuilder.Entity<Contract>() 
    .Map(m => 
    { 
        m.Properties(c => new { c.CustomerId, c.ContractId }); 
        m.ToTable("T_CONTRACTS"); 
    }) 
    .Map(m => 
    { 
        m.Properties(p => new { p.PersonID, p.Name }); 
        m.ToTable("T_PERSONS"); 
    });

https://msdn.microsoft.com/en-us/data/jj591617.aspx?f=255&MSPPError=-2147217396#2.7 https://msdn.microsoft.com/en-us/data/jj591617.aspx?f=255&MSPPError=-2147217396#2.7

Thanks a lot, I found others posts thanks to the keyword "Entity Splitting" : Entity splitting when key column has different names? 非常感谢,我发现其他帖子归功于关键字“Entity Splitting”: 当键列具有不同的名称时,实体分裂? Entity framework map entity to multiple tables? 实体框架将实体映射到多个表?

Here is my working configuration : 这是我的工作配置:

    public ContractConfiguration()
    {
        HasKey(c => c.CustomerId);
        Map(m =>
        {
            m.Property(c => c.ContractId).HasColumnName("CONTRACT_ID");
            m.Property(c => c.CustomerId).HasColumnName("CUSTOMER_ID");
            m.ToTable("T_CONTRACTS");
        });
        Map(m =>
        {
            m.Property(cust => cust.CustomerId).HasColumnName("PERSON_ID");
            m.Property(cust => cust.CustomerName).HasColumnName("NAME");
            m.ToTable("T_PERSONS");
        });
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM