Entity Framework 代码优先:在具有不同连接列的实体中展平组合
Entity Framework Code First : flatten composition in entity with different join column
我在使用 EntityFramework 使用 Code First 配置时遇到问题。
我有两个表:
+---------------+ +-------------+
| T_CONTRACTS | | T_PERSONS |
|---------------| |-------------|
|CONTRACT_ID | |PERSON_ID |
|CUSTOMER_ID | |NAME |
+---------------+ +-------------+
我想要一个 EF 实体:
public class Contract
{
public int ContractId { get; set; }
public int CustomerId { get; set; }
public string CustomerName { get; set; }
}
现在,我想将我的两个表映射到我的实体上。我命令这样做,我使用了 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");
});
}
}
废话来了,我不知道如何实现映射。
-如何将实体字段映射到两个表?
-如何连接外键具有不同列名的两个表(此处CUSTOMER_ID和PERSON_ID)?
非常感谢,
PS :我知道我们可以通过制作两个带有数据注释的实体来做到这一点。我想避免数据注释(因为关注点分离)并且我想保留一个实体。
首先,您的模型看起来不对。你(可能)想要这样的东西:
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?
}
现在您可以将流畅的代码更改为:
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);
}
}
现在您可以非常轻松地为 "flatten" 关系编写查询:
context.Contracts.Select(c => new {
c.ContractId,
CustomerId = c.PersonId,
CustomerName = c.Person.Name }).ToList();
编辑:重读后,我发现您可能想要的是 table 拆分,尽管第一种方法在 IMO 中更好,因为看起来您正在尝试将 ViewModel 构建到您的实体模型中不是 table 分裂的意图。 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
非常感谢,由于关键字 "Entity Splitting",我找到了其他帖子:
Entity splitting when key column has different names?
这是我的工作配置:
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");
});
}
我在使用 EntityFramework 使用 Code First 配置时遇到问题。 我有两个表:
+---------------+ +-------------+
| T_CONTRACTS | | T_PERSONS |
|---------------| |-------------|
|CONTRACT_ID | |PERSON_ID |
|CUSTOMER_ID | |NAME |
+---------------+ +-------------+
我想要一个 EF 实体:
public class Contract
{
public int ContractId { get; set; }
public int CustomerId { get; set; }
public string CustomerName { get; set; }
}
现在,我想将我的两个表映射到我的实体上。我命令这样做,我使用了 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");
});
}
}
废话来了,我不知道如何实现映射。
-如何将实体字段映射到两个表?
-如何连接外键具有不同列名的两个表(此处CUSTOMER_ID和PERSON_ID)?
非常感谢,
PS :我知道我们可以通过制作两个带有数据注释的实体来做到这一点。我想避免数据注释(因为关注点分离)并且我想保留一个实体。
首先,您的模型看起来不对。你(可能)想要这样的东西:
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?
}
现在您可以将流畅的代码更改为:
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);
}
}
现在您可以非常轻松地为 "flatten" 关系编写查询:
context.Contracts.Select(c => new {
c.ContractId,
CustomerId = c.PersonId,
CustomerName = c.Person.Name }).ToList();
编辑:重读后,我发现您可能想要的是 table 拆分,尽管第一种方法在 IMO 中更好,因为看起来您正在尝试将 ViewModel 构建到您的实体模型中不是 table 分裂的意图。 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
非常感谢,由于关键字 "Entity Splitting",我找到了其他帖子:
Entity splitting when key column has different names?
这是我的工作配置:
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");
});
}