鉴于课程:
public class User
{
public int Id { get; protected set; }
protected virtual ICollection<Role> UserRoles { get; set; }
public IEnumerable<Role> Roles
{
get { return new ReadOnlyCollection<Role>(UserRoles.ToArray()); }
}
}
如何使用EF6代码优先映射映射UserRoles?我不想暴露我的实体之外的任何ICollection功能。我也不想用持久性信息污染我的域模型。我希望它能保持持久性不可知。这意味着属性已经消失。
答案 0 :(得分:0)
也许this post可以帮助你 - 尽管它是EF 6 alpha,所以我不知道它是否仍适用。
从本质上讲,您可以在OnModelCreating()
方法中定义一个自定义约定,该约定包含所有非公共字段并将其包含在您的模型中(直接从链接页面获取代码片段):
public class MyContext : DbContext
{
// DbSets etc. defined here
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder
.Entities()
.Configure(c =>
{
var nonPublicProperties = c.ClrType.GetProperties(BindingFlags.NonPublic|BindingFlags.Instance);
foreach (var p in nonPublicProperties)
{
c.Property(p).HasColumnName(p.Name);
}
});
}
}
答案 1 :(得分:0)
我想出了如何使用反射来做到这一点。以下是它的要点:
internal class UserMapping : EntityTypeConfiguration<User>
{
public UserMapping()
{
ToTable("Users");
HasKey(u => u.Id);
Property(u => u.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.HasColumnName("UserID");
var userType = typeof (User);
var propertyInfo = userType.GetProperty("UserRoles", BindingFlags.NonPublic | BindingFlags.Instance);
var parameter = Expression.Parameter(typeof (User), "u");
var property = Expression.Property(parameter, propertyInfo);
var funcType = typeof (Func<,>).MakeGenericType(userType, typeof (ICollection<Role>));// propertyInfo.PropertyType);
var lambda = Expression.Lambda(funcType, property, parameter);
((ManyNavigationPropertyConfiguration<User, Role>)GetType().GetMethod("HasMany")
.MakeGenericMethod(typeof(Role))
.Invoke(this, new object[] { lambda }))
.WithMany()
.Map(m =>
{
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
m.ToTable("UserRoles");
});
}
}
}
很高兴@darkgray对这个答案很感兴趣:
How to convert PropertyInfo to property expression and use it to invoke generic method?