Как выполнить отложенную загрузку, не вызывая слой моего бизнес-объекта из моего объекта - PullRequest
2 голосов
/ 14 октября 2011

Простой вопрос У меня есть класс, скажем, человек, у которого в собственности есть член другого класса, скажем, Департамент.В терминах кода:

class person {
public string fname {get; set;}
public string lname {get; set;}
public Department d {get; set;}
}

Когда я загружаю человека, мой интерфейсный веб-сайт вызывает мой уровень бизнес-объектов, который затем вызывает мой уровень доступа к данным, что-то вроде этого:

website:
Person p;
p = BOL.GetPerson(1); //call function that returns a person

И на своем уровне бизнес-объектов я просто делаю некоторую бизнес-логику и вызываю уровень доступа к данным следующим образом:

BOL:

return DAL.GetPerson(1); //returns a person from my Data access layer

Внутри моего DAL я простовызов хранимой процедуры, которая извлекает эту информацию из таблицы человека.Единственное, что я не извлекаю данные отдела, потому что это довольно большая структура ...

Так что мой вопрос в том, как мне лениво загрузить этот объект отдела в мое свойство get БЕЗ моего объекта, зная или вызывая Business Objectслой.Кроме того, я считаю плохой практикой плотно связывать объект Department с объектом BOL.

Другими словами, я НЕ хочу делать это в своем классе:

public Department d {
  get 
     {
      if(d==null)
           {
            d = BOL.GetDepartmentInfo();
           }
     }
  set 
       {
        //some code
        }

То есть класс person должен содержать только соответствующую информацию о человеке, поэтому он действительно не должен знать о слое бизнес-объектов.

Как я могу решить эту проблему?

Edit

Вот свойство:

public FunctionalGroup Department
{
    get
    {
        if (Department == null)
        {
            Department = GetDepartment();
        }
    }
    set
    {
        Department = value;
    }
}

public Action<FunctionalGroup> GetDepartment { private get; set; }

Это жалуется, что Delegate Action does not take 0 arguments

Я пытался вызвать его с BOL так:

//assume already have an employee object
 e.GetDepartment = (id) => BOL.GetFunctionalGroup(e.FunctionalGroupID);

Изменить 2-й раз

В основном вот что у меня есть:

 private FunctionalGroup _d = null;

        public FunctionalGroup Department
        {
            get
            {
                if (_d == null)
                {
                    _d = GetDepartment();
                }
                return _d;
            }
            set
            {
                _d = value;
            }
        }

//        public Action<string, FunctionalGroup> GetDepartment { private get; set; }

        public Func<FunctionalGroup> GetDepartment { private get; set; }

Мой класс BOL пытается присвоить этому:

e.Department = (id) => BOL.GetFunctionalGroup(e.FunctionalGroupID);

Мой класс BOL говорит:

public static FunctionalGroup GetFunctionalGroup(string fgID)
 {
  return DAL.GetFunctionalGroup(fgID);
 }

Мой DAL выглядит следующим образом:

  /// <summary>
        /// Returns a functional group object along with all of its properties, otherwise null.
        /// </summary>
        /// <param name="fgID">String representation of a functional group (ex: "A-AD-C")</param>
        /// <returns>Functional group object with all associated properties, otherwise null.</returns>
        public static FunctionalGroup GetFunctionalGroup(string fgID)
        {
            FunctionalGroup fg = null;

            if (fgID.Length != 0)
            {
                  //connString = the string of our database app found in the resource file
                using (SqlConnection con = new SqlConnection(connString))
                {
                    using (SqlCommand cmd = new SqlCommand("EMPDLL_selFunctionalGroupByFunctionalGroupID", con))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.Add("@FunctionalGroupID", SqlDbType.VarChar).Value = fgID;
                        con.Open();

                        using (SqlDataReader reader = cmd.ExecuteReader())
                        {
                            if (reader.HasRows)
                            {
                                if (reader.Read())
                                {
                                    //found a func group
                                    fg = new FunctionalGroup((string)reader["FunctionalGroupID"],
                                                             (long)reader["ClientID"],
                                                             (string)reader["CostCenter"],
                                                             (string)reader["Description"],
                                                             (string)reader["Comments"],
                                                             (string)reader["AddedBy"],
                                                              reader["DateAdded"] == DBNull.Value ? null : (DateTime?)reader["DateAdded"],
                                                             (string)reader["ModifiedBy"],
                                                             reader["DateModified"] == DBNull.Value ? null : (DateTime?)reader["DateModified"],
                                                             (bool)reader["Inactive"]);
                                }
                            }
                        }
                    }
                }
            }
            return fg;
        }

Окончательное редактирование

Завершено использованием моего BOl с этим:

e.GetDepartment = () => BOL.GetFunctionalGroup(e.FunctionalGroupID);

И мой класс сотрудников с этим:

 private FunctionalGroup _d = null;

        public FunctionalGroup Department
        {
            get
            {
                if (_d == null)
                {
                    _d = GetDepartment();
                }
                return _d;
            }
            set
            {
                _d = value;
            }
        }

        public Func<FunctionalGroup> GetDepartment { private get; set; }

1 Ответ

3 голосов
/ 14 октября 2011

Вы можете дать объекту объекта метод обратного вызова, который может загрузить отдел для этого сотрудника:

class person {

  private Department _department = null;

  public Func<Department> GetDepartment { private get; set; }

  public string fname { get; set; }
  public string lname { get; set; }

  public Department d {
    get {
      if (_department == null) {
        _department = GetDepartment();
      }
      return _department;
    }
  }

}

Когда вы получаете объект person на бизнес-уровне:

p.GetDepartment = () => BOL.GetDepartment(1);
...