MVC EntityFramework Code-First 迁移 - Seed() 因 AmbiguousMatchException 而失败?
MVC EntityFramework Code-First Migrations - Seed() Failing with AmbiguousMatchException?
我正在开发一个有点简单的 InventoryTracker MVC5 应用程序,其中我在将 LocalDatabase 设置为 Seed()
.
时遇到了一些问题
当我在下面的代码中 运行 update-database
命令时,我在行 context.INV_Assets.AddRange(invAssets)
中得到如下异常:
An exception of type 'System.Reflection.AmbiguousMatchException' occurred in mscorlib.dll but was not handled in user code. Additional information: Ambiguous match found.
有人知道我的 INV_Assets - Seed()
中是什么导致了这个问题吗?没有 InnerException,我似乎无法获得更多详细信息。
代码:
internal sealed class Configuration : DbMigrationsConfiguration<InventoryTracker.DAL.InventoryTrackerContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(InventoryTracker.DAL.InventoryTrackerContext context)
{
if (System.Diagnostics.Debugger.IsAttached == false)
{
System.Diagnostics.Debugger.Launch();
}
List<INV_Locations> invLocs = getLocations();
context.INV_Locations.AddRange(invLocs);
context.SaveChanges();
List<INV_Manufacturers> invManufacturers = getManufacturers();
context.INV_Manufacturers.AddRange(invManufacturers);
context.SaveChanges();
List<INV_Models> invModels = getModels();
context.INV_Models.AddRange(invModels);
context.SaveChanges();
List<INV_Statuses> invStatuses = getStatuses();
context.INV_Statuses.AddRange(invStatuses);
context.SaveChanges();
List<INV_Types> invTypes = getTypes();
context.INV_Types.AddRange(invTypes);
context.SaveChanges();
List<INV_Vendors> invVendors = getVendors();
context.INV_Vendors.AddRange(invVendors);
context.SaveChanges(); // Everything OK to this point.
List<INV_Assets> invAssets = getAssets();
context.INV_Assets.AddRange(invAssets); // System.Reflection.AmbiguousMatchException!
context.SaveChanges();
}
private List<INV_Assets> getAssets()
{
List<INV_Assets> testAssets = new List<INV_Assets>
{
new INV_Assets
{
Id = 1,
ip_address = "10.10.135.38",
mac_address = "10.10.177.44",
note = "",
owner = "John Smith",
cost = 35,
po_number = "G348",
invoice_number = 1447,
serial_number = "JX14582Y",
asset_tag_number = "293548195023",
//acquired_date = Convert.ToDateTime(10212014),
acquired_date = DateTime.ParseExact("10212014", "MMddyyyy", CultureInfo.InvariantCulture),
disposed_date = null,
created_by = "Admin",
created_date = DateTime.Now,
modified_by = "Admin",
modified_date = DateTime.Now,
Location_Id = 1,
Manufacturer_Id = 1,
Model_Id = 1,
Status_Id = 2,
Type_Id = 3,
Vendor_Id = 3
}
};
return testAssets;
}
编辑:
INV_Assets.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using GridMvc.DataAnnotations;
using System.Web.Mvc;
using InventoryTracker.Models;
namespace InventoryTracker.Models
{
[GridTable(PagingEnabled = true, PageSize = 30)]
public class INV_Assets
{
// Setting GridColumn Annotations allows you to use AutoGenerateColumns on view to auto create the Grid based on the model.
public int Id { get; set; }
public int Model_Id { get; set; }
[ForeignKey("Model_Id")]
public virtual INV_Models model_id { get; set; }
[Required]
public int Manufacturer_Id { get; set; }
[ForeignKey("Manufacturer_Id")]
public virtual INV_Manufacturers manufacturer_id { get; set; }
[Required]
public int Type_Id { get; set; }
[ForeignKey("Type_Id")]
public virtual INV_Types type_id { get; set; }
[Required]
public int Location_Id { get; set; }
[ForeignKey("Location_Id")]
public virtual INV_Locations location_id { get; set; }
public int Vendor_Id { get; set; }
[ForeignKey("Vendor_Id")]
public virtual INV_Vendors vendor_id { get; set; }
[Required]
public int Status_Id { get; set; }
[ForeignKey("Status_Id")]
public virtual INV_Statuses status_id { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public decimal cost { get; set; }
public string po_number { get; set; }
public int invoice_number{ get; set; }
[Required]
public string serial_number { get; set; }
[Required]
public string asset_tag_number { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? acquired_date { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? disposed_date { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime created_date { get; set; }
[Required]
public string created_by { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime modified_date { get; set; }
public string modified_by { get; set; }
// Flag to specify if item is available? (Not signed out, not auctioned, recycled, etc.)
//public bool available { get; set; }
}
}
EDIT2:
Package Manager Console
中的完整结果,从输入命令 update-database
到 Ambiguous Match found
的结果:
PM> update-database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
No pending explicit migrations.
Running Seed method.
System.Reflection.AmbiguousMatchException: Ambiguous match found.
at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetProperty(String name, BindingFlags bindingAttr)
at System.Linq.Expressions.Expression.PropertyOrField(Expression expression, String propertyOrFieldName)
at System.Data.Entity.Core.Objects.Internal.EntityProxyFactory.CreateBaseGetter(Type declaringType, PropertyInfo propertyInfo)
at System.Data.Entity.Core.Objects.Internal.PocoPropertyAccessorStrategy.GetNavigationPropertyValue(RelatedEnd relatedEnd)
at System.Data.Entity.Core.Objects.Internal.EntityWrapper`1.GetNavigationPropertyValue(RelatedEnd relatedEnd)
at System.Data.Entity.Core.Objects.EntityEntry.FixupFKValuesFromNonAddedReferences()
at System.Data.Entity.Core.Objects.ObjectContext.AddSingleObject(EntitySet entitySet, IEntityWrapper wrappedEntity, String argumentName)
at System.Data.Entity.Core.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
at System.Data.Entity.Internal.Linq.InternalSet`1.<AddRange>b__f(Object entity)
at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action`1 action, EntityState newState, IEnumerable entities, String methodName)
at System.Data.Entity.Internal.Linq.InternalSet`1.AddRange(IEnumerable entities)
at System.Data.Entity.DbSet`1.AddRange(IEnumerable`1 entities)
at InventoryTracker.Migrations.Configuration.Seed(InventoryTrackerContext context) in c:\James-Projects\InventoryTracker\InventoryTracker\Migrations\Configuration.cs:line 91
at System.Data.Entity.Migrations.DbMigrationsConfiguration`1.OnSeed(DbContext context)
at System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase()
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Ambiguous match found.
再问好分析疯子:)
好吧,如果你看这里 http://msdn.microsoft.com/en-us/library/system.reflection.ambiguousmatchexception%28v=vs.110%29.aspx
然后你会看到那句话:"The exception that is thrown when binding to a member results in more than one member matching the binding criteria. This class cannot be inherited."
您在 INV_Assets 中是否有更多我们看不到的房产?
你能告诉我们 class 吗?
您的问题出在非常相似的 属性 名称中。例如在 INV_Assets
你有
public int Model_Id { get; set; }
[ForeignKey("Model_Id")]
public virtual INV_Models model_id { get; set; }
两者的名字几乎相同。区别仅在于第一个符号大小写。基于堆栈跟踪和 Entity framework 来源,它在 EntityProxyFactory
class:
中做这样的事情
public virtual Func<object, object> CreateBaseGetter(Type declaringType, PropertyInfo propertyInfo)
{
Func<object, object> nonProxyGetter =
((Expression<Func<object, object>>) (instance
=>
Expression.PropertyOrField(
(Expression) Expression.Convert(instance, declaringType),
propertyInfo.Name))
).Compile();
它将 属性 名称作为字符串传递。而Reflection无法理解属性应该使用什么,因为有两个同名但大小写不同的属性。
这是一个具有相同逻辑的示例程序,它也因相同的 Ambiguous match found.
异常而失败 - https://dotnetfiddle.net/BUIAwK
像往常一样,在 属性 名称中使用 ID
命名的引用对象,因此您只需将代码更新为
public int Model_Id { get; set; }
[ForeignKey("Model_Id")]
public virtual INV_Models Model { get; set; }
我正在开发一个有点简单的 InventoryTracker MVC5 应用程序,其中我在将 LocalDatabase 设置为 Seed()
.
当我在下面的代码中 运行 update-database
命令时,我在行 context.INV_Assets.AddRange(invAssets)
中得到如下异常:
An exception of type 'System.Reflection.AmbiguousMatchException' occurred in mscorlib.dll but was not handled in user code. Additional information: Ambiguous match found.
有人知道我的 INV_Assets - Seed()
中是什么导致了这个问题吗?没有 InnerException,我似乎无法获得更多详细信息。
代码:
internal sealed class Configuration : DbMigrationsConfiguration<InventoryTracker.DAL.InventoryTrackerContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(InventoryTracker.DAL.InventoryTrackerContext context)
{
if (System.Diagnostics.Debugger.IsAttached == false)
{
System.Diagnostics.Debugger.Launch();
}
List<INV_Locations> invLocs = getLocations();
context.INV_Locations.AddRange(invLocs);
context.SaveChanges();
List<INV_Manufacturers> invManufacturers = getManufacturers();
context.INV_Manufacturers.AddRange(invManufacturers);
context.SaveChanges();
List<INV_Models> invModels = getModels();
context.INV_Models.AddRange(invModels);
context.SaveChanges();
List<INV_Statuses> invStatuses = getStatuses();
context.INV_Statuses.AddRange(invStatuses);
context.SaveChanges();
List<INV_Types> invTypes = getTypes();
context.INV_Types.AddRange(invTypes);
context.SaveChanges();
List<INV_Vendors> invVendors = getVendors();
context.INV_Vendors.AddRange(invVendors);
context.SaveChanges(); // Everything OK to this point.
List<INV_Assets> invAssets = getAssets();
context.INV_Assets.AddRange(invAssets); // System.Reflection.AmbiguousMatchException!
context.SaveChanges();
}
private List<INV_Assets> getAssets()
{
List<INV_Assets> testAssets = new List<INV_Assets>
{
new INV_Assets
{
Id = 1,
ip_address = "10.10.135.38",
mac_address = "10.10.177.44",
note = "",
owner = "John Smith",
cost = 35,
po_number = "G348",
invoice_number = 1447,
serial_number = "JX14582Y",
asset_tag_number = "293548195023",
//acquired_date = Convert.ToDateTime(10212014),
acquired_date = DateTime.ParseExact("10212014", "MMddyyyy", CultureInfo.InvariantCulture),
disposed_date = null,
created_by = "Admin",
created_date = DateTime.Now,
modified_by = "Admin",
modified_date = DateTime.Now,
Location_Id = 1,
Manufacturer_Id = 1,
Model_Id = 1,
Status_Id = 2,
Type_Id = 3,
Vendor_Id = 3
}
};
return testAssets;
}
编辑:
INV_Assets.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using GridMvc.DataAnnotations;
using System.Web.Mvc;
using InventoryTracker.Models;
namespace InventoryTracker.Models
{
[GridTable(PagingEnabled = true, PageSize = 30)]
public class INV_Assets
{
// Setting GridColumn Annotations allows you to use AutoGenerateColumns on view to auto create the Grid based on the model.
public int Id { get; set; }
public int Model_Id { get; set; }
[ForeignKey("Model_Id")]
public virtual INV_Models model_id { get; set; }
[Required]
public int Manufacturer_Id { get; set; }
[ForeignKey("Manufacturer_Id")]
public virtual INV_Manufacturers manufacturer_id { get; set; }
[Required]
public int Type_Id { get; set; }
[ForeignKey("Type_Id")]
public virtual INV_Types type_id { get; set; }
[Required]
public int Location_Id { get; set; }
[ForeignKey("Location_Id")]
public virtual INV_Locations location_id { get; set; }
public int Vendor_Id { get; set; }
[ForeignKey("Vendor_Id")]
public virtual INV_Vendors vendor_id { get; set; }
[Required]
public int Status_Id { get; set; }
[ForeignKey("Status_Id")]
public virtual INV_Statuses status_id { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public decimal cost { get; set; }
public string po_number { get; set; }
public int invoice_number{ get; set; }
[Required]
public string serial_number { get; set; }
[Required]
public string asset_tag_number { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? acquired_date { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? disposed_date { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime created_date { get; set; }
[Required]
public string created_by { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime modified_date { get; set; }
public string modified_by { get; set; }
// Flag to specify if item is available? (Not signed out, not auctioned, recycled, etc.)
//public bool available { get; set; }
}
}
EDIT2:
Package Manager Console
中的完整结果,从输入命令 update-database
到 Ambiguous Match found
的结果:
PM> update-database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
No pending explicit migrations.
Running Seed method.
System.Reflection.AmbiguousMatchException: Ambiguous match found.
at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetProperty(String name, BindingFlags bindingAttr)
at System.Linq.Expressions.Expression.PropertyOrField(Expression expression, String propertyOrFieldName)
at System.Data.Entity.Core.Objects.Internal.EntityProxyFactory.CreateBaseGetter(Type declaringType, PropertyInfo propertyInfo)
at System.Data.Entity.Core.Objects.Internal.PocoPropertyAccessorStrategy.GetNavigationPropertyValue(RelatedEnd relatedEnd)
at System.Data.Entity.Core.Objects.Internal.EntityWrapper`1.GetNavigationPropertyValue(RelatedEnd relatedEnd)
at System.Data.Entity.Core.Objects.EntityEntry.FixupFKValuesFromNonAddedReferences()
at System.Data.Entity.Core.Objects.ObjectContext.AddSingleObject(EntitySet entitySet, IEntityWrapper wrappedEntity, String argumentName)
at System.Data.Entity.Core.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
at System.Data.Entity.Internal.Linq.InternalSet`1.<AddRange>b__f(Object entity)
at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action`1 action, EntityState newState, IEnumerable entities, String methodName)
at System.Data.Entity.Internal.Linq.InternalSet`1.AddRange(IEnumerable entities)
at System.Data.Entity.DbSet`1.AddRange(IEnumerable`1 entities)
at InventoryTracker.Migrations.Configuration.Seed(InventoryTrackerContext context) in c:\James-Projects\InventoryTracker\InventoryTracker\Migrations\Configuration.cs:line 91
at System.Data.Entity.Migrations.DbMigrationsConfiguration`1.OnSeed(DbContext context)
at System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase()
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Ambiguous match found.
再问好分析疯子:)
好吧,如果你看这里 http://msdn.microsoft.com/en-us/library/system.reflection.ambiguousmatchexception%28v=vs.110%29.aspx 然后你会看到那句话:"The exception that is thrown when binding to a member results in more than one member matching the binding criteria. This class cannot be inherited."
您在 INV_Assets 中是否有更多我们看不到的房产? 你能告诉我们 class 吗?
您的问题出在非常相似的 属性 名称中。例如在 INV_Assets
你有
public int Model_Id { get; set; }
[ForeignKey("Model_Id")]
public virtual INV_Models model_id { get; set; }
两者的名字几乎相同。区别仅在于第一个符号大小写。基于堆栈跟踪和 Entity framework 来源,它在 EntityProxyFactory
class:
public virtual Func<object, object> CreateBaseGetter(Type declaringType, PropertyInfo propertyInfo)
{
Func<object, object> nonProxyGetter =
((Expression<Func<object, object>>) (instance
=>
Expression.PropertyOrField(
(Expression) Expression.Convert(instance, declaringType),
propertyInfo.Name))
).Compile();
它将 属性 名称作为字符串传递。而Reflection无法理解属性应该使用什么,因为有两个同名但大小写不同的属性。
这是一个具有相同逻辑的示例程序,它也因相同的 Ambiguous match found.
异常而失败 - https://dotnetfiddle.net/BUIAwK
像往常一样,在 属性 名称中使用 ID
命名的引用对象,因此您只需将代码更新为
public int Model_Id { get; set; }
[ForeignKey("Model_Id")]
public virtual INV_Models Model { get; set; }