我有两个多对多关系的实体,它们不遵循代码优先命名约定,我必须找到一种方法来覆盖它。
第一个实体:
public class User
{
public int UserId { get; set; }
public string Username { get; set; }
public virtual ICollection<Rule> { get; set; }
}
第二实体:
public class Rule
{
public int RuleId { get; set; }
public string Description { get; set; }
public virtual ICollection<User> { get; set; }
}
我在这两个经典映射之间有一个表(名称为UserRule
,复合主键由2个列(UserId, RuleId
)和相应的外键组成)
我使用的dbcontext就是这个:
public class DataContext : DbContext
{
public IDbSet<User> Users { get; private set; }
public IDbSet<Rule> Rules { get; private set; }
private const string ConnectionStringName = "connectionstring";
public DataContext() : base(ConnectionStringName)
{
Configuration.LazyLoadingEnabled = true;
Rules = Set<Rule>();
Users = Set<User>();
}
protected override void OnModelCreating(DbModelBuilder builder)
{
// use this to disable database migrations and not use metadata inside database
Database.SetInitializer<DataContext>(null);
// setup MaestroAgentConfig to its table
builder.Configurations.Add(new UserTable());
// setup SecurityRule to its table
builder.Configurations.Add(new RuleTable());
base.OnModelCreating(builder);
}
public override int SaveChanges()
{
return base.SaveChanges();
}
}
我的映射表是:
public class UserTable : EntityTypeConfiguration<User>
{
public UserProfileTable()
{
Property(x => x.UserId).HasColumnName("UserId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasMany(x => x.SecurityRules)
.WithMany(x => x.UserProfiles)
.Map(map =>
{
map.MapRightKey("UserId");
map.MapRightKey("RuleId");
map.ToTable("UserRule");
});
ToTable("User");
}
}
和:
public class RuleTable : EntityTypeConfiguration<Rule>
{
public RuleTable()
{
Property(x => x.RuleId).HasColumnName("RuleId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasKey(x => x.RuleId);
ToTable("Rule");
}
}
然而,当EF查询数据库时,它看起来像这样:
exec sp_executesql N'
SELECT TOP (1)
[Extent1].[UserId] AS [UserId],
{ other fields }
FROM
[dbo].[UserProfile] AS [Extent1]
WHERE
[Extent1].[UserName] = @p__linq__0',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'EMYODE\erick.girard'
和:
exec sp_executesql N'
SELECT
[Extent2].[RuleId] AS [RuleId],
[Extent2].[Description] AS [Description]
FROM
[dbo].[UserRule] AS [Extent1]
INNER JOIN
[dbo].[Rule] AS [Extent2] ON [Extent1].[RuleId] = [Extent2].[RuleId]
WHERE
[Extent1].[User_UserId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=37
现在在第2次请求中,我找不到仅在UserId
表
UserRule
”的方法
我该如何设法做到这一点?
(编辑) 我尝试删除以下3个约定,但到目前为止它没有改变任何内容:
builder.Conventions.Remove<PluralizingEntitySetNameConvention>();
builder.Conventions.Remove<NavigationPropertyNameForeignKeyDiscoveryConvention>();
builder.Conventions.Remove<TypeNameForeignKeyDiscoveryConvention>();
答案 0 :(得分:0)
您的代码是精确副本还是伪代码?
准确地粘贴你的代码,我得到了相同的结果 -
但是,您要映射映射表的右侧两次:
map.MapRightKey("UserId");
map.MapRightKey("RuleId");
我将top命令更改为映射到左键
map.MapLeftKey("UserId");
map.MapRightKey("RuleId");
并为我修好了。