ASP.NET - C# 反射:AddObject 在运行时导致 "Ambiguous match found exception"
ASP.NET - C# Reflection: AddObject results in "Ambiguous match found exception" during Runtime
我正在开发 Web 应用程序的保存配置文件部分(在 ASP.NET/C# 中),但是,每当代码尝试保存时,我都会收到 "Ambiguous match found" 异常通过在运行时调用每个 "AddObject" 来创建新的配置文件。部分代码如下:
using System;
using System.ComponentModel.Composition;
using System.Linq;
using Itok.DataAccess.Interfaces;
using System.Collections.Generic;
using Itok.Entities;
namespace Itok.DataAccess.Repositories
{
[Export(typeof(IProfileRepository))]
public class ProfileRepository : IProfileRepository
{
private Connection conn;
public Int32 SaveProfile(Profile profile)
{
Int32 profileID1 = 0;
Boolean HasAttributeId = false;
profile.LastUpdateDate = DateTime.Now;
using(ItokDataContext dc = conn.GetContext())
{
if (profile.ProfileID > 0)
{
dc.Profiles.Attach(new Profile { ProfileID = profile.ProfileID });
dc.Profiles.ApplyCurrentValues(profile);
if (profile.Attributes != null)
{
foreach(ProfileAttribute item in profile.Attributes)
{
dc.ProfileAttributes.Attach(new ProfileAttribute
{ ProfileAttributeID = item.ProfileAttributeID,
});
dc.ProfileAttributes.ApplyCurrentValues(item);
}
}
}
else
{
profile.CreateDate = DateTime.Now;
//when working with new profile we don't expect attributes to be null, but check anyway
if (profile.Attributes != null)
{
foreach (ProfileAttribute item in profile.Attributes)
{
dc.ProfileAttributes.AddObject(new ProfileAttribute
{
ProfileAttributeID = item.ProfileAttributeID,
ProfileAttributeTypeID = item.ProfileAttributeTypeID,
ProfileID = item.ProfileID,
Response = item.Response,
CreateDate = item.CreateDate,
TimeStamp = item.TimeStamp
});
HasAttributeId = true;
}
}
dc.Profiles.AddObject(profile);
}
dc.SaveChanges();
profileID1 = profile.ProfileID;
if (HasAttributeId)
{
var result = from pa in dc.ProfileAttributes.Include("ProfileAttributeType")
where pa.ProfileID == profileID1
select pa;
profile.Attributes = result.ToList();
foreach (ProfileAttribute item in profile.ProfileAttributes)
{
item.profileAttributeType = item.ProfileAttributeType;
}
}
}
return profileID1;
}
}
}
ItokModel.context.cs包括以下代码:
namespace Itok.Entities
{
public partial class ItokDataContext : ObjectContext
{
public const string ConnectionString = "name=ItokDataContext";
public const string ContainerName = "ItokDataContext";
#region Constructors
public ObjectSet<ProfileAttribute> ProfileAttributes
{
get { return _profileAttributes ?? (_profileAttributes = CreateObjectSet<ProfileAttribute>("ProfileAttributes")); }
}
private ObjectSet<ProfileAttribute> _profileAttributes;
}
}
Profile.cs包括以下代码:
namespace Itok.Entities
{
public partial class Profile
{
public List<ProfileAttribute> Attributes { get; set; }
public LevelOfExperienceType levelOfExperienceType { get; set; }
public Profile()
{
Attributes = new List<ProfileAttribute>();
}
}
}
这里是 StackTrace:
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.Objects.Internal.EntityProxyFactory.CreateBaseGetter(Type declaringType, PropertyInfo propertyInfo)
at System.Data.Objects.Internal.PocoPropertyAccessorStrategy.GetNavigationPropertyValue(RelatedEnd relatedEnd)
at System.Data.Objects.Internal.EntityWrapper`1.GetNavigationPropertyValue(RelatedEnd relatedEnd)
at System.Data.Objects.EntityEntry.FixupFKValuesFromNonAddedReferences()
at System.Data.Objects.ObjectContext.AddSingleObject(EntitySet entitySet, IEntityWrapper wrappedEntity, String argumentName)
at System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
at System.Data.Objects.ObjectSet`1.AddObject(TEntity entity)
at Itok.DataAccess.Repositories.ProfileRepository.SaveProfile(Profile profile) in C:\Users\S400\Documents\Visual Studio 2010\Projects\Itok\Itok\DataAccess\Repositories\ProfileRepository.cs:line 84
有没有人知道如何避免这个异常?
我成功清除了异常。感谢大家的好评和回复。
但对于那些仍然有困难并为了节省查找异常的时间的人,您可能会发现以下步骤有助于更轻松地遵循和清除异常:
不要通过 google 搜索太多实例来分散自己的注意力,这些实例可能无法完全满足您的情况(尽管其中许多是指令性的)。事实上,最可靠的方法是依靠 MSDN 说明;
出现AmbiguousMatchException的情况包括:
2-1。一个类型包含两个具有相同名称但参数数量不同的索引属性。要解决歧义,请使用指定参数类型的 GetProperty 方法的重载。
2-2。派生类型使用 new 修饰符(在 Visual Basic 中为 Shadows)声明一个 属性,它隐藏同名的继承 属性。要解决歧义,请包含 BindingFlags.DeclaredOnly 以将搜索限制为非继承的成员。
- 虽然有点费时,但查找 "method name dropdown list" 的效率很高,而且您很有可能在那里找到 "same name methods or properties"。
最好的问候
巴巴克苏丹
我正在开发 Web 应用程序的保存配置文件部分(在 ASP.NET/C# 中),但是,每当代码尝试保存时,我都会收到 "Ambiguous match found" 异常通过在运行时调用每个 "AddObject" 来创建新的配置文件。部分代码如下:
using System;
using System.ComponentModel.Composition;
using System.Linq;
using Itok.DataAccess.Interfaces;
using System.Collections.Generic;
using Itok.Entities;
namespace Itok.DataAccess.Repositories
{
[Export(typeof(IProfileRepository))]
public class ProfileRepository : IProfileRepository
{
private Connection conn;
public Int32 SaveProfile(Profile profile)
{
Int32 profileID1 = 0;
Boolean HasAttributeId = false;
profile.LastUpdateDate = DateTime.Now;
using(ItokDataContext dc = conn.GetContext())
{
if (profile.ProfileID > 0)
{
dc.Profiles.Attach(new Profile { ProfileID = profile.ProfileID });
dc.Profiles.ApplyCurrentValues(profile);
if (profile.Attributes != null)
{
foreach(ProfileAttribute item in profile.Attributes)
{
dc.ProfileAttributes.Attach(new ProfileAttribute
{ ProfileAttributeID = item.ProfileAttributeID,
});
dc.ProfileAttributes.ApplyCurrentValues(item);
}
}
}
else
{
profile.CreateDate = DateTime.Now;
//when working with new profile we don't expect attributes to be null, but check anyway
if (profile.Attributes != null)
{
foreach (ProfileAttribute item in profile.Attributes)
{
dc.ProfileAttributes.AddObject(new ProfileAttribute
{
ProfileAttributeID = item.ProfileAttributeID,
ProfileAttributeTypeID = item.ProfileAttributeTypeID,
ProfileID = item.ProfileID,
Response = item.Response,
CreateDate = item.CreateDate,
TimeStamp = item.TimeStamp
});
HasAttributeId = true;
}
}
dc.Profiles.AddObject(profile);
}
dc.SaveChanges();
profileID1 = profile.ProfileID;
if (HasAttributeId)
{
var result = from pa in dc.ProfileAttributes.Include("ProfileAttributeType")
where pa.ProfileID == profileID1
select pa;
profile.Attributes = result.ToList();
foreach (ProfileAttribute item in profile.ProfileAttributes)
{
item.profileAttributeType = item.ProfileAttributeType;
}
}
}
return profileID1;
}
}
}
ItokModel.context.cs包括以下代码:
namespace Itok.Entities
{
public partial class ItokDataContext : ObjectContext
{
public const string ConnectionString = "name=ItokDataContext";
public const string ContainerName = "ItokDataContext";
#region Constructors
public ObjectSet<ProfileAttribute> ProfileAttributes
{
get { return _profileAttributes ?? (_profileAttributes = CreateObjectSet<ProfileAttribute>("ProfileAttributes")); }
}
private ObjectSet<ProfileAttribute> _profileAttributes;
}
}
Profile.cs包括以下代码:
namespace Itok.Entities
{
public partial class Profile
{
public List<ProfileAttribute> Attributes { get; set; }
public LevelOfExperienceType levelOfExperienceType { get; set; }
public Profile()
{
Attributes = new List<ProfileAttribute>();
}
}
}
这里是 StackTrace:
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.Objects.Internal.EntityProxyFactory.CreateBaseGetter(Type declaringType, PropertyInfo propertyInfo)
at System.Data.Objects.Internal.PocoPropertyAccessorStrategy.GetNavigationPropertyValue(RelatedEnd relatedEnd)
at System.Data.Objects.Internal.EntityWrapper`1.GetNavigationPropertyValue(RelatedEnd relatedEnd)
at System.Data.Objects.EntityEntry.FixupFKValuesFromNonAddedReferences()
at System.Data.Objects.ObjectContext.AddSingleObject(EntitySet entitySet, IEntityWrapper wrappedEntity, String argumentName)
at System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
at System.Data.Objects.ObjectSet`1.AddObject(TEntity entity)
at Itok.DataAccess.Repositories.ProfileRepository.SaveProfile(Profile profile) in C:\Users\S400\Documents\Visual Studio 2010\Projects\Itok\Itok\DataAccess\Repositories\ProfileRepository.cs:line 84
有没有人知道如何避免这个异常?
我成功清除了异常。感谢大家的好评和回复。
但对于那些仍然有困难并为了节省查找异常的时间的人,您可能会发现以下步骤有助于更轻松地遵循和清除异常:
不要通过 google 搜索太多实例来分散自己的注意力,这些实例可能无法完全满足您的情况(尽管其中许多是指令性的)。事实上,最可靠的方法是依靠 MSDN 说明;
出现AmbiguousMatchException的情况包括:
2-1。一个类型包含两个具有相同名称但参数数量不同的索引属性。要解决歧义,请使用指定参数类型的 GetProperty 方法的重载。
2-2。派生类型使用 new 修饰符(在 Visual Basic 中为 Shadows)声明一个 属性,它隐藏同名的继承 属性。要解决歧义,请包含 BindingFlags.DeclaredOnly 以将搜索限制为非继承的成员。
- 虽然有点费时,但查找 "method name dropdown list" 的效率很高,而且您很有可能在那里找到 "same name methods or properties"。
最好的问候 巴巴克苏丹