>

5 개의 쿼리 선택으로 해결 한 복잡한 선택 절차가 있으므로 여기에 게시하여 조금 단축하는 방법에 대한 제안을 얻을 수 있습니다. 누군가가 단일 쿼리 선택을하도록 도울 수 있기를 바랍니다. 여기에서 nhibernate 쿼리를 사용하고 있습니다.

7 개의 테이블이 있습니다

  • t_user
  • t_category
  • t_event
  • t_announcement
  • t_event_follower
  • t_event_register
  • t_event_subcribe

아래 클래스에서 그것들을 표현할 것입니다 :

class User {
  int id;
  string username;
  IList<Registration> registrations;
  IList<Category> subscribes;
  IList<Event> follows;
}
class Category {
  int id;
  string description;
  IList<User> subscribers;
}
class Event{
  int id;
  string title;
  Category category;
  IList<Registration> registrations;
  IList<User> followers;
  IList<Announcement> announcements;
}
class Announcement {
  int id;
  string title;
  Event event;
  bool isForFollower;
  bool isForRegister;
  bool isForSubscriber;
}
class Registration {
  int id;
  Event event;
  User user;
  string additionalInfo;
  RegistrationStatus status;
}
enum UserRole {
  PUBLIC,
  FOLLOWER,
  SUBSCRIBER,
  REGISTERED
}

목표는 해당 이벤트의 사용자 역할에 따라 모든 공지 사항을 1 이벤트로 표시하는 것입니다. 내가 먼저 한 일은 아래 코드로 사용자 역할을 목록에 채우는 것입니다.

User requester = _userRepo.SearchBy(username); // 1 query for user detail
// 3 lazy load objects make nhibernate to load the object from db, i assume it takes 3 query select if objects haven't load in session
bool isFollower = requester.Follows.Any(eventz => eventz.Id == eventId);
bool isSubscriber = requester.Subscribes.Any(category => category.Events.Any(eventz => eventz.Id == eventId));
bool isRegistered = requester.Registrations.Any(registration => registration.Event.Id == eventId);
var userRoleList= new List<UserRole>();
if (isFollower) userRoleList.Add(UserRole.FOLLOWER);
if (isSubscriber) userRoleList.Add(UserRole.SUBSCRIBER);
if (isRegistered) userRoleList.Add(UserRole.REGISTERED);

아래 저장소 계층의 코드로 마지막에 쿼리에 대한 동적 분리를 만듭니다.

Disjunction filterRestriction = Restrictions.Disjunction();
// this condition to select announcement which is for public not specific
filterRestriction.Add(Restrictions.Where<Announcement>(a => a.IsForFollower == false
                                                            && a.IsForSubscriber == false
                                                            && a.IsForRegistered == false));
foreach (UserRole role in userRoleList)
{
    switch (role)
    {
        case UserRole.FOLLOWER:
            filterRestriction.Add(Restrictions.Where<Announcement>(a => a.IsForFollower));
            break;
        case UserRole.SUBSCRIBER:
            filterRestriction.Add(Restrictions.Where<Announcement>(a => a.IsForSubscriber));
            break;
        case UserRole.REGISTERED:
            filterRestriction.Add(Restrictions.Where<Announcement>(a => a.IsForRegistered));
            break;
    }
}
//this is the last query transaction, so total 5 times select from db CMIIW, 
return _session.QueryOver<Announcement>()
               .Where(filterRestriction)
               .And(a => a.Event.Id == id)
               .List();

위 코드에서 쿼리 결과는 사용자가 관련 이벤트에서 수행 한 역할을 기반으로 공개 발표와 특정 발표를 보여줍니다.

이 문제를 해결할 수있는 가장 간단한 해결 책임을 인정합니다. 누군가가 쿼리를 통해 한 번의 간단한 작업으로 제안하거나 재 작업 할 수 있습니까? 아니면 더 나은 쿼리로 다시 만들 수 있습니까?

  • 답변 # 1

    웹 애플리케이션 인 경우 HttpModule을 사용하여 세션 관리를 수행 할 수 있습니다. 세션을 열고 트랜잭션을 시작하여 모든 웹 요청을 시작하십시오. 모든 웹 요청이 끝나면 트랜잭션을 커밋하고 세션을 닫습니다.

    모든 히트를 단일 트랜잭션으로 데이터베이스에 래핑하는 한 효율성에 대해 너무 걱정할 필요가 없습니다.

  • 이전 permissions - 내 조직의 추종자 수 - 링크드 인 api
  • 다음 javascript - 태그에서 숫자 반환