我找到了一些有关如何使用ef4创建工作单元的示例,我没有使用过di/ioc,我想使事情保持简单,这是一个示例(获得90%的启发),我认为还可以,但是由于我正在研究从现在开始使用的一种模式,我想最后一次提出意见。

 public interface IUnitOfWork
 {
     void Save();
 }

public partial class TemplateEntities : ObjectContext, IUnitOfWork
{
    ....
    public void Save()
    {
        SaveChanges();
    }
}
public interface IUserRepository
{
    User GetUser(string username);
    string GetUserNameByEmail(string email);
    void AddUser(User userToAdd);
    void UpdateUser(User userToUpdate);
    void DeleteUser(User userToDelete);
    //some other
}
public class UserRepository : IUserRepository, IDisposable
{
    public TemplateEntities ctx;
    public UserRepository(IUnitOfWork unit)
    {
        ctx = unit as TemplateEntities;
    }
    public User GetUser(string username)
    {
        return (from u in ctx.Users
                where u.UserName == username
                select u).SingleOrDefault();
    }
    public string GetUserNameByEmail(string email)
    {
        return (from u in ctx.Users
                where u.Email == email
                select u.UserName).SingleOrDefault();
    }
    public void AddUser(User userToAdd)
    {
        ctx.Users.AddObject(userToAdd);
    }
    public void UpdateUser(User userToUpdate)
    {
        ctx.Users.Attach(userToUpdate);
        ctx.ObjectStateManager.ChangeObjectState(userToUpdate, System.Data.EntityState.Modified);
    }
    public void DeleteUser(User userToDelete)
    {
        ctx.Users.Attach(userToDelete);
        ctx.ObjectStateManager.ChangeObjectState(userToDelete, System.Data.EntityState.Deleted);
    }
    public void Dispose()
    {
        if (ctx != null)
            ctx.Dispose();
    }
}

最后
    public class BogusMembership : MembershipProvider
    {
        public MembershipCreateStatus CreateUser(string username, string password, string email, bool autoemail, string fullname)
        {
            IUnitOfWork ctx = new TemplateEntities();
            using (UserRepository rep = new UserRepository(ctx))
            {
                using (TransactionScope tran = new TransactionScope())
                {
                    if (rep.GetUser(username) != null)
                        return MembershipCreateStatus.DuplicateUserName;
                    if (requiresUniqueEmail && !String.IsNullOrEmpty(rep.GetUserNameByEmail(email)))
                        return MembershipCreateStatus.DuplicateEmail;
                    User userToCreate = new User
                    {
                        UserName = username,
                        PassWord = EncodePassword(password),
                        FullName = fullname,
                        Email = email,
                        AutoEmail = autoemail
                    };
                    try
                    {
                        rep.AddUser(userToCreate);
                        ctx.Save();
                        tran.Complete();
                        return MembershipCreateStatus.Success;
                    }
                    catch
                    {
                        return MembershipCreateStatus.UserRejected;
                    }
                }
            }
        }
    }

除去IUnitOfWork和IDisposal之后,CreateUser如下所示:
        public MembershipCreateStatus CreateUser(string username, string password, string email, bool autoemail, string fullname)
        {
            using (TransactionScope tran = new TransactionScope())
            {
                using (TemplateEntities ctx = new TemplateEntities())
                {
                    UserRepository rep = new UserRepository(ctx);
                    //OtherRepository rep2 = new OtherRepository(ctx);
                    if (rep.GetUser(username) != null)
                        return MembershipCreateStatus.DuplicateUserName;
                    if (requiresUniqueEmail && !String.IsNullOrEmpty(rep.GetUserNameByEmail(email)))
                        return MembershipCreateStatus.DuplicateEmail;
                    User userToCreate = new User
                    {
                        UserName = username,
                        PassWord = EncodePassword(password),
                        FullName = fullname,
                        Email = email,
                        AutoEmail = autoemail
                    };
                    try
                    {
                        rep.AddUser(userToCreate);
                        ctx.SaveChanges();
                        tran.Complete();
                        return MembershipCreateStatus.Success;
                    }
                    catch
                    {
                        return MembershipCreateStatus.UserRejected;
                    }
                }
            }
        }

最佳答案

这看起来基本上可以。一些建议:

  • 您不应该让存储库处置TemplateEntities。这样做的原因是,当您在一个事务中需要两个存储库时,就会遇到问题。您应该将处置TemplateEntities的职责移到与TransactionScope相同的级别上;
  • TransactionScope应该移到更高的级别。最好在TemplateEntities内实例化TransactionScope
  • 如果它不包含功能,则无需创建Save包装器。如果在void SaveChanges()接口(interface)上指定IUnitOfWork,则将选择SaveChangesTemplateEntities
  • 就我个人而言,我没有string GetUserNameByEmail(...),而是User GetUserByEmail(...),因为这也可以满足您的目的,并且您的优势在于,在以后需要User GetUserByEmail(...)时,没有两种通过电子邮件地址进行搜索的方法;
  • 您可能需要考虑将ctx设为私有(private),或者至少将私有(private)设置者设为public TemplateEntities Ctx { get; private set; }
  • 您可以使用类似下面的示例的方法来创建一个抽象存储库。从长远来看,这将节省您大量的乏味输入:

  • --
    public interface IRepository<TEntity>
    {
        void Delete(TEntity entity);
    
        /* ... */
    }
    
    public abstract class AbstractRepository<TEntity> : IRepository<TEntity>
    {
        public TemplateEntities ctx;
    
        public AbstractRepository(IUnitOfWork unit)
        {
            ctx = unit as TemplateEntities;
        }
    
        protected abstract ObjectSet<TEntity> Entites { get; }
    
        public virtual void Delete(TEntity entity)
        {
            Entities.Attach(entity);
            ctx.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Deleted);
        }
    
        /* ... */
    }
    
    public interface IUserRepository : IRepository<User>
    {
        User GetUser(string username);
    
        /* ... */
    }
    
    public class UserRepository : AbstractRepository<User>, IUserRepository
    {
        public UserRepository(IUnitOfWork unit)
            : base(unit)
        {
        }
    
        protected override ObjectSet<User> Entites
        {
            get { return ctx.Users; }
        }
    
        public User GetUser(string username)
        {
            return (from u in ctx.Users
                    where u.UserName == username
                    select u).SingleOrDefault();
        }
    
        /* ... */
    }
    

    10-06 11:39