asp.net 학습 의 길 프로젝트 전체 프레임 워 크 간단 한 구축

최근 에 asp.net 뮤 직 비디오 에 관 한 지식 을 배 웠 기 때문에 작은 프로젝트 로 연습 하고 자신의 code 능력 과 사고력 을 향상 시 켜 야 합 니 다.그 전에 하 는 일 은 모두 간단 합 니 다.부 드 러 운 생 성 코드 를 직접 사용 하여 간단 한 3 층 구 조 를 만 드 는 것 을 프로젝트 의 전체적인 구조 로 하고 데이터 베이스 방문 층 은 ado.net 을 사 용 했 습 니 다.이렇게 하면 매우 번 거 롭 습 니 다.만약 에 프로젝트 가 데이터 베 이 스 를 바 꾸 려 면 데이터 베이스 에 표를 추가 하거나 표 에 특정한 필드 를 추가 하거나 ado.net 를 사용 하지 않 고 orm 프레임 워 크 로 데이터 베 이 스 를 방문 하 는 등 전체적인 프로젝트 가 움 직 이면 다른 번 거 로 움 을 제기 해 야 합 니 다.이 문 제 를 해결 하기 위해 우 리 는 어떻게 구축 하 는 지 다시 생각해 야 합 니 다.데이터 베이스 방문 층 데이터 베이스 방문 구동 층-모두 가 EF 를 알 고 있 습 니 다.NH 와 Ado.net 또는 당신 이 스스로 실현 한 것 입 니 다.이런 것들 은 모두 우리 가 데이터 베 이 스 를 방문 하거나 데이터 베 이 스 를 조작 하 는 데 다 리 를 놓 은 것 입 니 다.물론 데이터 베 이 스 는 서로 다른 데이터 베이스 일 수도 있 습 니 다.이런 것들 은 모두 프로젝트 의 수요 에 따라 정 해진 것 입 니 다.어느 것 을 선택 하 는 지 는 상황 에 따라 정 해 야 합 니 다.여기 서 저 는 EF-model-first 를 사 용 했 습 니 다.저 는 직접 edmx 에서 모델 을 디자인 한 다음 에 실체 와 데이터 베 이 스구체 적 으로 다음 과 같 습 니 다.간단 한 권한 관리(아직 완전히 실현 되 지 않 았 습 니 다)를 했 습 니 다.
 
public class BaseRepository<T>:IDAL.IBaseRepository<T> where T:class
{
private DbContext container = EFContentFactory.GetCurrentContext();
#region
public T AddEntity(T entity)
{
container.Set<T>().Add(entity);
return entity;
}
#endregion
#region
public bool DeleteEntity(T entity)
{
container.Set<T>().Attach(entity);
container.Entry(entity).State = EntityState.Deleted;
return true;
}
#endregion
#region
public bool UpdateEntity(T entity)
{
container.Set<T>().Attach(entity);
container.Entry(entity).State = EntityState.Modified;
return true;
}
#endregion
#region
public IQueryable<T> GetEntities(Func<T, bool> lambdaWhere)
{
IQueryable<T> entities = container.Set<T>().Where(lambdaWhere).AsQueryable();
return entities;
}
#endregion
#region
public IQueryable<T> GetEntitiesByPageIndex<TS>(int pageIndex, int pageSize, out int totalCount, Func<T, bool> lambdaWhere, Func<T, TS> orderByRole, bool descending)
{
var temp = container.Set<T>().Where(lambdaWhere).AsQueryable();
totalCount = temp.Count();
if (descending)
{
temp = temp.OrderByDescending(orderByRole)
.Skip(pageSize * (pageIndex - 1))
.Take(pageSize).AsQueryable();
}
else
{
temp = temp.OrderBy(orderByRole)
.Skip(pageSize * (pageIndex - 1))
.Take(pageSize).AsQueryable();
}
return temp;
}
#endregion
}
이 단계 에 와 서 저 는 자신의 데이터 베이스 방문 층 이 다 쓴 줄 알 았 습 니 다.그리고 업무 논리 층 의 물건 을 쓸 수 있 습 니 다.그렇지 않 습 니 다.생각해 보 세 요.만약 에 데이터 라 이브 러 리 를 바 꾸 거나 ef 또는 ado.net 으로 바 꾸 려 면 전체 프로젝트 의 모든 층 을 교체 해 야 합 니 다.업 무량 을 크게 늘 렸 습 니 다.여기 서 우 리 는 데이터 액세스 층 을 한 층 더 추상 화 할 수 있 습 니 다.이 는 인터페이스 가 필요 합 니 다.IDAL.IBase Repository는 대체적으로 우리 의 bll 층 을 생각해 보 세 요.인터페이스 가 없 으 면 우 리 는 dal.xreposcory=new xreposcory()를 직접 이렇게 씁 니 다.상투적인 쓰 기 는 앞에서 말 했 듯 이 유지 가능성 의 교체 성 이 크게 떨어진다.우 리 는 지금 이렇게 IDAL.xx reposcory=new xx reposcory()를 쓸 수 있다.그러면 우리 가 DAL 층 을 교체 할 때 BLL 층 뿌리 는 당신 이 어떻게 실현 하 는 지 에 관심 을 가 질 필요 가 없다.이 점 은 매우 중요 하 다.인 터 페 이 스 는 하나의 계약 에 해당 하 며,당신 이 어떤 기능 을 실현 해 야 하 는 지 를 제약 하고 있다.우리 가 만약 에 기능 을 추가 하려 면 인터페이스 에 직접 추가 할 수 있다.인 터 페 이 스 는 일부 인터페이스 가 필요 하 다.예 를 들 어 내 가 제시 한 상기 코드 와 같이 기본 클래스 는 인터페이스 가 필요 하고 하위 클래스 도 필요 하 다.그러면 우 리 는 데이터 베이스 인터페이스 층 을 추상 화 할 수 있다.추상 공장 과 간단 한 공장 은 업무 층 과 데이터 베이스 방문 층 에 대해 다시 읽 는 추상 화 를 할 수 있다.여기 서 우 리 는 공장 을 사용 해 야 한다.사실은 매우 간단 하 다.공장 류 에서 꺼 낸 dal 층 의 유형 을 IDAL 의 인터페이스
 
public static class ShopDaoFactory
{
public static IUserInfoRepository UserInfoRepository
{
get{return new UserInfoRepository();}
}
public static IRoleRepository RoleRepository
{
get{return new RoleRepository();}
}
}
로 돌아 가면 업무 층 이 인 터 페 이 스 를 받 을 때 어떻게 실현 하 는 지 에 관심 을 가 질 필요 가 없다.그러면 추상 적 인 공장 이기 도 한다.물론 너 도 추상 적 인 공장 을 이용 하여 반사 와 배치 와 캐 시 를 이용 하여 실현 할 수 있다.그러나 일반적인 상황 에서 간단 한 공장 은 충분 하 다.여 기 는 데이터베이스 액세스 층 의 입구 에 해당 합 니 다.업무 논리 층 의 기본 클래스 와 하위 클래스 는 우리 의 실체 모델 이 많 을 때 우 리 는 기본 클래스 가 없 으 면 중복 되 는 것 을 써 야 합 니 다.우 리 는 지금 이러한 중복 되 는 것 을 기본 클래스 에 넣 어서 우리 에 게 실현 시 켜 야 합 니 다.Dal 층 처럼 우 리 는 기본 클래스 를 정 의 했 습 니 다.그러나 BLL 층 에서 우 리 는 문 제 를 만 날 수 있 습 니 다.IDAL.IBase Repository는 공장 에서 인 터 페 이 스 를 어떻게 얻 었 는 지......................................................우 리 는 이 인 터 페 이 스 를 사용 해 야 하기 때문에 구조 함수 에서
 
public abstract class BaseService<T> :IBLL.IBaseService<T> where T:class, new ()
{
public BaseService()
{
GetInstance();
}
protected IDAL.IDbSession _DbSession = DbSeesionFactory.GetSession();
protected IDAL.IBaseRepository<T> CurrentRepository { get; set; }
public abstract void GetInstance();
public IQueryable<T> GetEntities(Func<T, bool> lambdaWhere)
{
//_DbSession.SavaChanges();
return CurrentRepository.GetEntities(lambdaWhere);
}
public bool DeleteEntity(T entity)
{
CurrentRepository.DeleteEntity(entity);
return _DbSession.SaveChanges() > 0;
}
public bool UpdateEntity(T entity)
{
CurrentRepository.UpdateEntity(entity);
return _DbSession.SaveChanges() > 0;
}
public T AddEntity(T entity)
{
var en = CurrentRepository.AddEntity(entity);
_DbSession.SaveChanges();
return en;
}
public IQueryable<T> GetEntitiesByPageIndex<TS>(int pageIndex, int pageSize, out int totalCount, Func<T, bool> lambdaWhere, Func<T, TS> orderByRole, bool descending)
{
return CurrentRepository.GetEntitiesByPageIndex(pageIndex, pageSize, out totalCount, lambdaWhere, orderByRole,
descending);
}
}
}
다른 업무 층 도 인 터 페 이 스 를 추상 화하 여 제약 해 야 한다.그러면 ui 층 도 당신 의 업무 층 이 어떻게 실현 하 는 지 에 관심 을 가 질 필요 가 없다.대응 하 는 이 인터페이스 에 대응 하 는 실현 클래스,두 가지 방법 SaveChanges(),exsql(EF 용 5.0+)과 현재 EF 스 레 드 류 컨 텍스트 의 savechhange()와 sql 문 구 를 실행 하 는 재생 값 을 되 돌려 줍 니 다.어떻게 하면 현재 프로 세 스 내 EF 컨 텍스트 가 하나 밖 에 없 는 지 확인 할 수 있 습 니까?우 리 는 다른 종 류 를 봅 니 다.
 
public partial class DbSession:IDAL.IDbSession
{
#region
//public IDAL.IRoleRepository RoleRepository
//{
// get { return new RoleRepository();}
//}
//public IDAL.IUserInfoRepository UserInfoRepository
//{
// get { return new UserInfoRepository();}
//}
#endregion
public int SaveChanges()
{
return EFContentFactory.GetCurrentContext().SaveChanges();
}
public int ExcuteSql(string strSql, System.Data.Objects.ObjectParameter[] parameters)
{
return EFContentFactory.GetCurrentContext().Database.ExecuteSqlCommand(strSql, parameters);
}
}
public class EFContentFactory
{
public static DbContext GetCurrentContext()
{
DbContext obj = CallContext.GetData("DbContext") as DbContext;
if (obj==null)
{
obj = new Model.DataContainer();
CallContext.SetData("DbContext",obj);
}
return obj;
}
}
CallContext 는 방법 호출 과 유사 한 스 레 드 로 컬 저장 소 전용 집합 대상 이 며,모든 논리 실행 스 레 드 에 유일한 데이터 슬롯 을 제공 합 니 다.데이터 슬롯 은 다른 논리 스 레 드 의 호출 컨 텍스트 간 에 공유 되 지 않 습 니 다.이것 은 msdn 에서 캡 처 한 말 입 니 다.몇 가지 방법 이 있 습 니 다.이 안에 우 리 는 setdata 와 getdata 를 사용 하여 컨 텍스트 스 레 드 내 에서 유일 하 게 확보 합 니 다.똑 같은 우 리 는 그 를 인터페이스 화 시 켜 공장 내 에서-
 
public class DbSeesionFactory
{
/// <summary>
/// dbsession
/// </summary>
/// <returns></returns>
public static IDAL.IDbSession GetSession()
{
IDAL.IDbSession _dbSession = CallContext.GetData("DbSession") as IDbSession;
if (_dbSession == null)
{
_dbSession = new DbSession();
CallContext.SetData("DbSession", _dbSession);
}
return _dbSession;
}
}
업무 층 의 하위 클래스 재 작성 방법 을 실현 할 때 이렇게 실현 합 니 다.같은 기본 클래스 추가:protected IDAL.IDbSessionDbSession = DbSeesionFactory.GetSession();
 
public partial class ActionInfoService:BaseService<ActionInfo>,IBLL.IActionInfoService
{
public override void GetInstance()
{
CurrentRepository = _DbSession.ActionInfoRepository;
}
}

public partial class R_UserInfo_ActionInfoService:BaseService<R_UserInfo_ActionInfo>,IBLL.IR_UserInfo_ActionInfoService
{
public override void GetInstance()
{
CurrentRepository = _DbSession.R_UserInfo_ActionInfoRepository;
}
}

public partial class RoleService:BaseService<Role>,IBLL.IRoleService
{
public override void GetInstance()
{
CurrentRepository = _DbSession.RoleRepository;
}
}
왜 그 랬 어 요?우리 가 EF 를 사용 할 때 예 를 들 어 한 가지 방법 에서 여러 개의 시 계 를 조작 하려 면 문맥 을 계속 사용 해 야 한다.그러면 우 리 는 많은 일 을 남 겨 두 고 마지막 에 바로dbsession.savechhange().대량 삭제 수정 등 작업 에 도달 할 수 있 습 니 다.구체 적 으로 저 를 보면 오늘 대량 삭제
 
public int DeleteUsers(List<int> list)
{
foreach (var i in list)
{
_DbSession.UserInfoRepository.DeleteEntity(new UserInfo() {ID = i});
}
return _DbSession.SaveChanges();
}
를 했 습 니 다.졸 립 습 니 다.요 며칠 동안 배 운 것 을 정리 해 보 니 많은 것 을 얻 었 습 니 다.그 안에 대해 잘 이해 하지 못 했 지만 천천히 보면 깨 달 았 습 니 다.대학 에 공유 하여 함께 공부 하 겠 습 니 다~

좋은 웹페이지 즐겨찾기