【发布时间】:2019-03-25 03:01:01
【问题描述】:
我正在尝试调试现有的 ASP.NET Web 应用程序并在登录时遇到异常:
类型参数不能从用法中推断出来。尝试明确指定类型参数。缺少潜在的异常处理
据我所知,发生错误是因为在运行以下代码时,varTypesToRegister 中加载了 duplicate 程序集:
var typesToRegister = Assembly.GetAssembly(assemblyClassType).GetTypes()
.Where(type => type.Namespace != null)
结果视图中有 91 个元素,最后 10 个元素似乎是重复的,因为它们已经存在于数组/列表的前 0 - 80 个项目中。第一个异常在元素 81 上引发(见下面的屏幕截图)。如您所见,元素 81 已作为元素 24 存在。因此,当尝试将现有的装配添加到模型构建器时会引发异常。
注意:assemblyClassType 只是传入的一个程序集。此代码似乎获取了所有项目程序集,尽管我不确定这是如何发生的或为什么会发生(我是该项目的新手,原始开发人员不可用)。
问题:有没有办法防止重复的程序集被加载到typesToRegister 中?或者,有没有办法阻止代码尝试将副本加载到模型构建器中:
foreach (Type type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance); // Exception thrown here
}
GroupMap.cs
public class GroupMap : EntityTypeConfiguration<Group>
{
public GroupMap()
{
Property(group => group.Name).IsRequired();
HasMany(group => group.Roles)
.WithMany(role => role.Groups)
.Map(m =>
{
m.MapLeftKey("GroupId");
m.MapRightKey("RoleId");
m.ToTable("GroupRoles");
});
HasMany(group => group.Members)
.WithMany(user => user.Groups)
.Map(m =>
{
m.MapLeftKey("GroupId");
m.MapRightKey("PersonId");
m.ToTable("GroupMembers");
});
}
}
Group.cs
public class Group : BaseEntity
{
private ICollection<Person> _members;
private ICollection<Role> _roles;
public Group()
{
_members = new HashSet<Person>();
_roles = new HashSet<Role>();
}
[Display(Name = "Group Name")]
[Required(ErrorMessage = "Group Name is required.")]
[MaxLength(100, ErrorMessage = "Group Name allows only 100 characters.")]
public string Name { get; set; }
public virtual ICollection<Person> Members
{
get { return _members; }
set { _members = value; }
}
public virtual ICollection<Role> Roles
{
get { return _roles; }
set { _roles = value; }
}
}
BaseDbContext.cs
public class BaseDbContext<TContext> : DbContext where TContext : DbContext, IDbContext, IObjectContextAdapter
{
static BaseDbContext()
{
Database.SetInitializer<TContext>(null);
}
public void RunConventions(DbModelBuilder modelBuilder, Type assemblyClassType)
{
// Change default conventions for cascade deletes
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
// Id property in everyclass is named class + Id (i.e CustomerId, JobId, VendorId)
// Id is always first column in table
// Could also explicitly determine as key using .Configure(p => p.IsKey() but EF already looks for property of name Id as primary key
modelBuilder.Properties()
.Where(p => p.Name == "Id")
.Configure(p => p.HasColumnOrder(0).HasColumnName((p.ClrPropertyInfo.ReflectedType == null ? "" : p.ClrPropertyInfo.ReflectedType.Name) + "Id"));
// Add Domain Entity Mapping Configurations
//var typesToRegister = Assembly.GetAssembly(assemblyClassType).GetTypes()
// .Where(type => type.Namespace != null);
var typesToRegister = Assembly.GetAssembly(typeof(DbContext)).GetTypes()
.Where(type => type.Namespace != null && type.Namespace.Equals(typeof(BaseDbContext<TContext>).Namespace))
.Where(type => type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (Type type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
}
}
【问题讨论】:
-
能否提供准确的错误信息?
-
@KirillPolishchuk 完成。
-
异常发生时正在执行的行是什么?
-
@StevePy 在第二个块中添加了代码注释。
modelBuilder.Configurations.Add(configurationInstance)。我正在准备一个屏幕截图来显示 ResultsView。 -
@JWeezy 我认为您应该检查 typesToRegister 每种类型是否属于 IEntityTypeConfiguration。
标签: c# asp.net asp.net-mvc entity-framework