我有一个自我引用表,在模型第一种方法中定义。但是,当尝试使用GenericRepository模式获取表中的行列表时,我得到一个异常
System.ArgumentException was unhandled by user code
Message=An item with the same key has already been added.
Source=mscorlib
StackTrace:
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Data.Objects.Internal.EntityProxyTypeInfo..ctor(Type proxyType, ClrEntityType ospaceEntityType, DynamicMethod initializeCollections, List`1 baseGetters, List`1 baseSetters)
at System.Data.Objects.Internal.EntityProxyFactory.BuildType(ModuleBuilder moduleBuilder, ClrEntityType ospaceEntityType)
at System.Data.Objects.Internal.EntityProxyFactory.TryCreateProxyType(EntityType ospaceEntityType)
at System.Data.Objects.Internal.EntityProxyFactory.GetProxyType(ClrEntityType ospaceEntityType)
at System.Data.Common.Internal.Materialization.Translator.Visit(EntityColumnMap columnMap, TranslatorArg arg)
at System.Data.Query.InternalTrees.EntityColumnMap.Accept[TResultType,TArgType](ColumnMapVisitorWithResults`2 visitor, TArgType arg)
at System.Data.Common.Internal.Materialization.Translator.HandleSpandexRecord(RecordColumnMap columnMap, TranslatorArg arg, RowType spanRowType)
at System.Data.Common.Internal.Materialization.Translator.Visit(RecordColumnMap columnMap, TranslatorArg arg)
at System.Data.Query.InternalTrees.RecordColumnMap.Accept[TResultType,TArgType](ColumnMapVisitorWithResults`2 visitor, TArgType arg)
at System.Data.Common.Internal.Materialization.Translator.ProcessCollectionColumnMap(CollectionColumnMap columnMap, TranslatorArg arg, ColumnMap discriminatorColumnMap, Object discriminatorValue)
at System.Data.Common.Internal.Materialization.Translator.Visit(SimpleCollectionColumnMap columnMap, TranslatorArg arg)
at System.Data.Query.InternalTrees.SimpleCollectionColumnMap.Accept[TResultType,TArgType](ColumnMapVisitorWithResults`2 visitor, TArgType arg)
at System.Data.Common.Internal.Materialization.Translator.TranslateColumnMap[TRequestedType](QueryCacheManager queryCacheManager, ColumnMap columnMap, MetadataWorkspace workspace, SpanIndex spanIndex, MergeOption mergeOption, Boolean valueLayer)
at System.Data.Common.Internal.Materialization.ShaperFactory.TypedShaperFactoryCreator`1.TypedCreate(QueryCacheManager cacheManager, ColumnMap columnMap, MetadataWorkspace metadata, SpanIndex spanInfo, MergeOption mergeOption, Boolean valueLayer)
at System.Data.Common.Internal.Materialization.ShaperFactory.Create(Type elementType, QueryCacheManager cacheManager, ColumnMap columnMap, MetadataWorkspace metadata, SpanIndex spanInfo, MergeOption mergeOption, Boolean valueLayer)
at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Span span, ReadOnlyCollection`1 compiledQueryParameters)
at System.Data.Objects.EntitySqlQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator()
at System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at MySite.DAL.GenericRepository`1.Get(Expression`1 filter, Func`2 orderBy, String includeProperties) in D:\....cs:line 52
at MySite.Controllers.MyController.PopulateDropDowns(MyTable data) in D:\....cs:line 429
at MySite.Controllers.MyController.AddEntry(Int32 id) in D:\....cs:line 394
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
InnerException:
还有另一个例外:
System.ArgumentException was unhandled by user code
Message=Duplicate type name within an assembly.
Source=mscorlib
StackTrace:
at System.Reflection.Emit.ModuleBuilder.CheckTypeNameConflict(String strTypeName, TypeBuilder enclosingType)
at System.Reflection.Emit.AssemblyBuilderData.CheckTypeNameConflict(String strTypeName, TypeBuilder enclosingType)
at System.Reflection.Emit.TypeBuilder.Init(String fullname, TypeAttributes attr, Type parent, Type[] interfaces, Module module, PackingSize iPackingSize, Int32 iTypeSize, TypeBuilder enclosingType)
at System.Reflection.Emit.ModuleBuilder.DefineType(String name, TypeAttributes attr, Type parent, Type[] interfaces)
at System.Data.Objects.Internal.EntityProxyFactory.ProxyTypeBuilder.get_TypeBuilder()
at System.Data.Objects.Internal.EntityProxyFactory.ProxyTypeBuilder.CreateType(ModuleBuilder moduleBuilder)
at System.Data.Objects.Internal.EntityProxyFactory.BuildType(ModuleBuilder moduleBuilder, ClrEntityType ospaceEntityType)
at System.Data.Objects.Internal.EntityProxyFactory.TryCreateProxyType(EntityType ospaceEntityType)
at System.Data.Objects.Internal.EntityProxyFactory.GetProxyType(ClrEntityType ospaceEntityType)
at System.Data.Common.Internal.Materialization.Translator.Visit(EntityColumnMap columnMap, TranslatorArg arg)
at System.Data.Query.InternalTrees.EntityColumnMap.Accept[TResultType,TArgType](ColumnMapVisitorWithResults`2 visitor, TArgType arg)
at System.Data.Common.Internal.Materialization.Translator.HandleSpandexRecord(RecordColumnMap columnMap, TranslatorArg arg, RowType spanRowType)
at System.Data.Common.Internal.Materialization.Translator.Visit(RecordColumnMap columnMap, TranslatorArg arg)
at System.Data.Query.InternalTrees.RecordColumnMap.Accept[TResultType,TArgType](ColumnMapVisitorWithResults`2 visitor, TArgType arg)
at System.Data.Common.Internal.Materialization.Translator.ProcessCollectionColumnMap(CollectionColumnMap columnMap, TranslatorArg arg, ColumnMap discriminatorColumnMap, Object discriminatorValue)
at System.Data.Common.Internal.Materialization.Translator.Visit(SimpleCollectionColumnMap columnMap, TranslatorArg arg)
at System.Data.Query.InternalTrees.SimpleCollectionColumnMap.Accept[TResultType,TArgType](ColumnMapVisitorWithResults`2 visitor, TArgType arg)
at System.Data.Common.Internal.Materialization.Translator.TranslateColumnMap[TRequestedType](QueryCacheManager queryCacheManager, ColumnMap columnMap, MetadataWorkspace workspace, SpanIndex spanIndex, MergeOption mergeOption, Boolean valueLayer)
at System.Data.Common.Internal.Materialization.ShaperFactory.TypedShaperFactoryCreator`1.TypedCreate(QueryCacheManager cacheManager, ColumnMap columnMap, MetadataWorkspace metadata, SpanIndex spanInfo, MergeOption mergeOption, Boolean valueLayer)
at System.Data.Common.Internal.Materialization.ShaperFactory.Create(Type elementType, QueryCacheManager cacheManager, ColumnMap columnMap, MetadataWorkspace metadata, SpanIndex spanInfo, MergeOption mergeOption, Boolean valueLayer)
at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Span span, ReadOnlyCollection`1 compiledQueryParameters)
at System.Data.Objects.EntitySqlQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator()
at System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at MySite.DAL.GenericRepository`1.Get(Expression`1 filter, Func`2 orderBy, String includeProperties) in D:\....cs:line 52
at MySite.Controllers.MyController.PopulateDropDowns(MyTable data) in D:\....cs:line 429
at MySite.Controllers.MyController.AddEntry(Int32 id) in D:\....cs:line 394
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
InnerException:
GenericRepository代码(在return query.ToList()
处失败)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.Entity;
using System.Linq.Expressions;
using MySite.Models;
namespace MySite.DAL
{
public class SortExpression<TEntity, TType>
{
Expression<Func<TEntity, TType>> SortProperty;
}
public class GenericRepository<TEntity> where TEntity : class
{
internal MySiteDBContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(MySiteDBContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
}
}
所有查询都包含unitOfWork.MyTableRepository.Get()
。从模型设计者生成的模型没有什么特别之处,它恰好引用自己。
public partial class MyTable
{
public MyTable()
{
}
public int Id { get; set; }
public string Name { get; set; }
public virtual MyTable Child { get; set; }
public virtual MyTable Parent { get; set; }
}
这种模式适用于其他表(不是自我引用本身),而不是这一个。
答案 0 :(得分:0)
添加外键ID可能会有所帮助:
public partial class MyTable
{
public MyTable()
{
}
public int Id { get; set; }
public string Name { get; set; }
public int? ChildId { get; set; }
public int? ParentId { get; set; }
public virtual MyTable Child { get; set; }
public virtual MyTable Parent { get; set; }
}
然后在OnModelCreating中执行以下操作:
modelBuilder.Entity<MyTable>()
.HasOptional(c => c.Child )
.WithMany()
.HasForeignKey(c => c.ChildId);
modelBuilder.Entity<MyTable>()
.HasOptional(c => c.Parent )
.WithMany()
.HasForeignKey(c => c.ParentId);