问题
I am using Entity Framework 4.3 code first
using an already existing database.
There is a Users table
that has the following columns:
- UserID (int)
- FirstName (string)
- Surname (string)
I have an association table called Impersonations
. The Impersonations table is an association table between a user table and the same user table. A user can have a list of users. Here is the Impersonations table
structure:
- ImpersonateID (int primary key)
- UserID (int FK to Users table's UserID column)
- ImpersonatedUserID (int FK to Users table's UserID column)
I have a User class with properties that I want mapped to these columns:
public class User : IEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmployeeNumber { get; set; }
public virtual ICollection<User> ImpersonatedUsers { get; set; }
public virtual ICollection<User> Users { get; set; }
}
In my db context class I have the following:
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new UserConfiguration());
}
User configuration:
class UserConfiguration : EntityTypeConfiguration<User>
{
internal UserConfiguration()
{
this.Property(x => x.Id).HasColumnName("UserID");
this.Property(x => x.LastName).HasColumnName("Surname");
this.Property(x => x.EmployeeNumber).HasColumnName("StaffNumber");
this.HasMany(i => i.Users)
.WithMany(c => c.ImpersonatedUsers)
.Map(mc =>
{
mc.MapLeftKey("UserID");
mc.MapRightKey("ImpersonatedUserID");
mc.ToTable("Impersonations");
});
}
}
Did I link this up correctly using Entity Framework? If I pass through a user id then a list of users needs to be returned that was marked as inpersonated users. How I do this? I have this but both User and ImpersonatedUsers are empty:
return DbContext.Users
.Include("ImpersonatedUsers")
.SingleOrDefault(x => x.Id == userId);
Lets say I have the following data in my Users table (id, first name, last name, employee number):
7 Craig Matthews 123456
8 Susan Renshaw 234567
9 Michelle du Toit 34567
And the following data in my Impersonations table (impersonated id, user id, impersonated user id):
1 7 8
2 7 9
So if I pass in a user id of 7 then it need to return records for users Susan Renshaw and Michelle du Toit.
Just for clarity if you are still confused...
I have a similar situation. I have a Products table and a Specifications table. These 2 are linked up by the assication table called ProductSpecifications. I am trying to achieve the same here, but the 2 tables would be the Users table and the association table is Impersonations.
回答1:
If I well understand, I think I have quite the same: a user is also a group and so can have members.
Here is an extract of my code:
public partial class User : AuthorizableBaseObject, IHasUID {
public User() {
Members = new List<User>();
}
public Guid UID { get; set; }
public DateTime EmailValidationDate { get; set; }
public String EMail { get; set; }
//public Int64 Id { get; set; }
public String Login { get; set; }
public String Password { get; set; }
public String Description { get; set; }
public DateTime LastConnectionDate { get; set; }
public Boolean CanConnect { get; set; }
public Boolean IsDisabled { get; set; }
public virtual List<User> Members { get; set; }
}
with the following configuration :
public class UserConfiguration : EntityTypeConfiguration<VDE.User> {
public UserConfiguration()
: base() {
ToTable("Users", "dbo");
Property(u => u.EMail).IsRequired().HasColumnType("nvarchar").HasMaxLength(100);
Property(u => u.Login).IsRequired().HasColumnType("nvarchar").HasMaxLength(20);
Property(u => u.Password).IsRequired().HasColumnType("nvarchar").HasMaxLength(50);
Property(u => u.Description).HasColumnType("nvarchar").HasMaxLength(200);
Property(u => u.LastConnectionDate).HasColumnType("datetime2");
HasMany(u => u.Members).WithMany().Map(m => m.MapLeftKey("UserId").MapRightKey("MemberId").ToTable("UserMembers"));
}
}
From here to get the members of a group the query is easy:
context.Users.Where(u => u.Id == someId).Select(u => u.Members).FirstOrDefault()
This will give an IEnumerable
回答2:
Try taking a look at this page on inheritance. Your explanation isn't great, but I think this is what you're trying to achieve.
回答3:
You must create a class for Impersonation and add it as a DBSet to the dbcontext. EF may make you put a [Key] attribute on the foreign key fields, along with [Column(Order = 0 or 1)].
Then you can lazy load the property:
public virtual List<Impersonation> UserImpersonations
{
get
{
if(_userImpersonations == null)
{
// Set _userImpersonations =
// lazy load using a linq to sql query where
// UserImpersonations.UserId = this.UserId
}
return __userImpersonations;
}
}
来源:https://stackoverflow.com/questions/11311272/how-to-handle-an-association-table-linking-the-same-2-tables