C# 我可以使用EF6代码优先映射来映射受保护的ICollection吗?
鉴于班级:C# 我可以使用EF6代码优先映射来映射受保护的ICollection吗?,c#,entity-framework,entity-framework-6,C#,Entity Framework,Entity Framework 6,鉴于班级: 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>(UserRole
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()); }
}
}
公共类用户
{
public int Id{get;protected set;}
受保护的虚拟ICollection用户角色{get;set;}
公共可数角色
{
获取{返回新的只读集合(UserRoles.ToArray());}
}
}
如何使用EF6代码优先映射映射用户角色?我不想在实体之外公开任何ICollection功能。我也不想用持久性信息污染我的域模型。我希望它保持不可知论。这意味着属性已过时。也许可以帮助您-尽管它是EF 6 alpha,所以我不知道它是否仍然适用
本质上,您可以在OnModelCreating()
方法中定义一个自定义约定,该约定接受所有非公共字段并将它们包含在模型中(代码片段直接从链接页面获取):
我想出了如何使用反射来实现这一点。其要点如下:
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");
});
}
}
}
内部类用户映射:EntityTypeConfiguration
{
公共用户映射()
{
ToTable(“用户”);
HasKey(u=>u.Id);
属性(u=>u.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.HasColumnName(“用户ID”);
var userType=typeof(用户);
var propertyInfo=userType.GetProperty(“UserRoles”,BindingFlags.NonPublic | BindingFlags.Instance);
变量参数=表达式参数(用户类型,“u”);
var property=Expression.property(参数,propertyInfo);
var funcType=typeof(Func).MakeGenericType(userType,typeof(ICollection));//propertyInfo.PropertyType);
var lambda=Expression.lambda(funcType,property,parameter);
((ManyNavigationPropertyConfiguration)GetType().GetMethod(“HasMany”)
.MakeGenericMethod(类型(角色))
.Invoke(这个新对象[]{lambda}))
.有很多
.Map(m=>
{
m、 MapLeftKey(“用户ID”);
m、 MapRightKey(“RoleId”);
m、 ToTable(“用户角色”);
});
}
}
}
非常感谢@darkgray的回答:
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");
});
}
}
}