I have the following database schema which I can't change:
The relationship between the TM_USER
and TM_USER_DETAIL
tables uses the USR_ID
and UDT_USR_ID
columns. The data type of USR_ID
is int
.
The relationship between the TM_USER
and TM_MEMBERSHIP_USERS
tables uses the USR_USER_KEY
and USR_ID
columns. The data type of USR_USER_KEY
is a guid
represented as a string
.
My question is how to map this using Entity Framework?
Here is my entity:
public class User
{
// from table TM_USER
public int Id { get; set; }
public string Username { get; set; }
public string Key { get; set; }
// from table TM_USER_DETAIL
public string Forename { get; set; }
public string Surname { get; set; }
// from table TM_MEMBERSHIP_USERS
public bool IsApproved { get; set; }
}
And my entity configuration:
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
Map(map =>
{
map.Properties(p => new { p.Key, p.Id, p.Username });
map.ToTable("TM_USER");
map.Property(p => p.Key).HasColumnName("USR_USER_KEY");
map.Property(p => p.Id).HasColumnName("USR_ID");
map.Property(p => p.Username).HasColumnName("USR_USER_NAME");
});
Map(map =>
{
map.Properties(p => new { p.Forename, p.Surname });
map.ToTable("TM_USER_DETAIL");
map.Property(p => p.Id).HasColumnName("UDT_USR_ID");
map.Property(p => p.Forename).HasColumnName("UDT_FORENAME");
map.Property(p => p.Surname).HasColumnName("UDT_SURNAME");
});
Map(map =>
{
map.Properties(p => new { p.IsApproved });
map.ToTable("TM_MEMBERSHIP_USERS");
map.Property(p => p.Key).HasColumnName("USR_ID");
map.Property(p => p.IsApproved).HasColumnName("USR_ISAPPROVED");
});
HasKey(user => user.Id);
}
}
When I try to query the Users
, I get the following error:
Properties for type 'User' can only be mapped once. The non-key property 'Id' is mapped more than once. Ensure the Properties method specifies each non-key property only once.
Is it possible to configure EF to map a single entity to three tables in this way using different keys for each relationship?
I have posted a sample solution here: https://github.com/kevinkuszyk/entity-splitting
This is not possible. You should split your model into different models. Furthermore, the relationship does not make sense for me. In your schema, TM_USER
has many TM_USER_DETAIL
, that relationship allows an User to have several forenames and surnames. I think that was not your intention. In a common scenario, the TM_USER
has only one TM_USER_DETAIL
. So, your model should be something like this:
TM_USER
-------------
UserId - PK
Username
Key
Deleted
TM_USER_DETAIL
---------------
UserId - PK - FK TM_USER
Forename
Surname
To make the model even simpler, we can merge TM_USER_DETAIL
with TM_USER
. Like this:
TM_USER
-------------
UserId - PK
Username
Key
Forename
Surname
Deleted
The same thing values to the relationship between TM_User
and TM_MEMBERSHIP_USERS
. So, we can merge them. Like this:
TM_USER
-------------
UserId - PK
Username
Key
Forename
Surname
IsApproved
Deleted
Now, we have to create the User
class in order to use it in the Entity Framework.
public class User
{
// from table TM_USER
public int Id { get; set; }
public string Username { get; set; }
public string Key { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public bool IsApproved { get; set; }
}
Mapping:
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
ToTable("TM_USER");
Property(p => p.Key).HasColumnName("USR_USER_KEY");
Property(p => p.Id).HasColumnName("USR_ID");
Property(p => p.Username).HasColumnName("USR_USER_NAME");
Property(p => p.Forename).HasColumnName("UDT_FORENAME");
Property(p => p.Surname).HasColumnName("UDT_SURNAME");
Property(p => p.IsApproved).HasColumnName("USR_ISAPPROVED");
HasKey(user => user.Id);
}
}
If you still want to use 3 different tables, you have to create 3 different classes, with their respective properties, mapping them to their respective tables.
Hope it helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.