已添加具有相同密钥的项目 - 实体框架4.1模型优先

时间:2011-11-07 19:08:23

标签: entity-framework-4.1

我有一个自我引用表,在模型第一种方法中定义。但是,当尝试使用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; }
}

这种模式适用于其他表(不是自我引用本身),而不是这一个。

1 个答案:

答案 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);