0

Microsoft Contoso University のサンプルで使用されている Generic Repository/Unit of work コードを使用しています。

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net- mvc-アプリケーション

そして、データベース レベルでエラーが発生するまで、正常に動作します (保存、取得、更新、削除など)。特に、渡されたテキストに対してフィールドの 1 つが短すぎる挿入を作成しようとしました。もちろん失敗しました。エラーは try/catch ブロックでトラップされ、エラー メッセージが表示されます。問題は、その後、フォームに新しい情報を入力しても (これは正しいテキスト サイズのように有効です)、まったく同じエラー (フィールド XYZ は文字列または配列型でなければならない) で、SaveChanges メソッドが失敗し続けることです。最大長は '999' です)。デバッグを停止し、ASP.NET プロジェクトの実行を再開するまで停止します。

明確にするために、これは私が持っているコードです: (GenericRepository.cs)

public class GenericRepository<TEntity> where TEntity : class
{
    internal DBORAContext context;
    internal DbSet<TEntity> dbSet;

    public GenericRepository(DBORAContext 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;
    }                
}

(UnitOfWork.cs)

public class UnitOfWork : IDisposable 
    {
        private DBORAContext context = new DBORAContext();        
        private GenericRepository<Activity> activityRepository;        
        public GenericRepository<Activity> ActivityRepository
        {
            get
            {

                if (this.activityRepository == null)
                {
                    this.activityRepository = new GenericRepository<Activity>(context);
                }
                return activityRepository;
            }
        }        

        public void Save()
        {                            
            context.SaveChanges();
        }                

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        } 
    }

これは、この特定のオブジェクト (Activity.cs) のリポジトリを呼び出すクラスです。

public class Activity
    {
        private static readonly UnitOfWork unitOfWork = new UnitOfWork();                

        public static POCO.Activity Get(Guid activityId)
        {
            try
            {
                var thisActivity = unitOfWork.ActivityRepository.Get(a => a.ACTIVITYID == activityId).FirstOrDefault();

                if (null != thisActivity)
                {
                    return thisActivity;
                }
                return null;
            }
            catch (Exception ex)
            {                
                new Logger(ex.Message);
                return null;
            }            
        }

        public static POCO.Activity Add(POCO.Activity activityToInsert)
        {
            try
            {
                unitOfWork.ActivityRepository.Insert(activityToInsert);
                unitOfWork.Save();
                return activityToInsert;
            }            
            catch (Exception ex)
            {
                //log.Error("Add activity error", ex);
                new Logger(ex.Message);
                throw;
            }
        }

        public static bool Update(POCO.Activity activityToUpdate)
        {
            try
            {
                unitOfWork.ActivityRepository.Update(activityToUpdate);
                unitOfWork.Save();
                return true;
            }            
            catch (Exception ex)
            {
                //log.Error("update activity error", ex);
                new Logger(ex.Message);
                throw;
            }
        }     

        public static bool Delete(POCO.Activity activityToDelete)
        {
            try
            {
                unitOfWork.ActivityRepository.Delete(activityToDelete);
                unitOfWork.Save();
                return true;
            }            
            catch (Exception ex)
            {                
                new Logger(ex.Message);
                throw;
            }
        }
    }

Oracle データベースで EF 4.3 を使用しています。助けてください。

4

2 に答える 2

0

問題は、作業単位がシングルトンであることです。作業単位には、より小さなスコープが必要です。これが Web アプリの場合、http コンテキストは UoW のスコープに適したオブジェクトです。

request.begin -> UoW の開始 request.end -> UoW の完了

これがサービスの場合、サービスへの各リクエストで Uow を開始/終了できます。

これがリッチ クライアントの場合は、各 UI フォームにスコープを設定できます。

于 2013-06-26T18:25:05.727 に答える