实例化后如何立即调用方法

时间:2019-03-06 17:53:21

标签: c# asp.net-mvc asp.net-mvc-5

我有一个控制器,该控制器调用api以获取Positions和Employees的列表。首先,它将api结果放入模型类-IDMSElements(1)。然后,控制器获取IDMSElements对象,并将其转换为PositionSlots对象(2)。然后,需要使用数据库中的其他数据更新PositionSlots对象(3)。因此,在我的控制器的简化版本中,我有:

        (1) IDMSElements elements = getslots.CopyDocToElements(doc);
        (2) PositionSlots myslots = (PositionSlots)elements;         
        (3) myslots.UpdateDetails(db);

我担心myslots.UpdateDetails(db),因为控制器中的其他代码取决于已运行的UpdateDetails。我希望在创建PositionSlots对象时默认运行UpdateDetails。但是我认为可能不应该在构造函数中进行多个数据库调用。如何实现,以便在实例化PositionSlots对象之后自动调用UpdateDetails?

非常感谢您!

控制器:

[Authorize]
public class PSListController : Controller
{
    private static readonly log4net.ILog _logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    private PositionControlContext db = new PositionControlContext();
    private GetPositionSlots getslots = new GetPositionSlots();

    ...

    public async Task<ActionResult> ByCostCenter(int costCenter)
    {

        string ssapiuri = getslots.BuildAPIuri($"/current/?UDAKunit={costCenter.ToString()}");
        _logger.Debug($"{ssapiuri.ToString()}");


        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();

        HttpResponseMessage result = await getslots.GetDataFromIDMSapi(ssapiuri);

        stopWatch.Stop();
        _logger.Debug($"Response received.  Milliseconds elapsed: {stopWatch.Elapsed.TotalMilliseconds.ToString()}");

        if (result.StatusCode != HttpStatusCode.OK)
        {
            _logger.Debug("Error retrieving data from API.  Milliseconds elapsed: " + stopWatch.Elapsed.TotalMilliseconds.ToString());
            throw new HttpException(404, "NotFound");
        }


        stopWatch.Restart();

        XDocument doc = XDocument.Load(result.Content.ReadAsStreamAsync().Result);

        stopWatch.Stop();
        _logger.Debug($"API result loaded into XDocument.  Milliseconds elapsed: {stopWatch.Elapsed.TotalMilliseconds.ToString()}\n");
        _logger.Debug(doc.ToString());


        IDMSElements elements = getslots.CopyDocToElements(doc);
        XMLDocStats docstats = new XMLDocStats(elements);
        _logger.Debug(docstats.ToString());

        PositionSlots myslots = (PositionSlots)elements;
        myslots.UpdateDetails(db);

        //because this is dependent upon UpdatePositionSlotId having been run
        //need to find a way to force UpdateDetails to run other than calling from Controller??
        var mainPositionSlots = myslots.PositionsCurrentAndActive;


        var budget = db.Database.SqlQuery<Budget>("GetBudgetForCostCenter @costCenter = {0}", costCenter);
        List<Budget> budgetRows = budget.ToList();

        JobClassGroups jobClassGroups = new JobClassGroups(mainPositionSlots, budgetRows);

        Department dept = db.Departments.AsNoTracking().Where(d => d.CostCenter == costCenter).SingleOrDefault();

        var model = new ByCostCenter_vm(dept, myslots, jobClassGroups);

        ViewBag.stats = docstats.ToString();

        return View("ByCostCenter", model);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }

}

IDMSElements类:

public class IDMSElements
{
    //properties
    public ICollection<IDMSElementData> Elements { get; set; }


    //constructors
    public IDMSElements() { }
    public IDMSElements(ICollection<IDMSElementData> elList)
    {
        Elements = elList;
    }

    //methods
    public static explicit operator PositionSlots(IDMSElements obj)
    {
        //this is assuming we are looking at a list of elements
        //that contains the "current" positions

        Dictionary<string, PositionSlotDetail> positionSlots = new Dictionary<string, PositionSlotDetail>();

        var sorted = from element in obj.Elements
                     orderby element.positionNbr
                     select element;

        foreach (IDMSElementData el in sorted)
        {
            if (!positionSlots.ContainsKey(el.positionNbr))
            {
                PositionSlotDetail psd = new PositionSlotDetail
                {
                    CostCenter = Int32.Parse(el.UDAKunit),
                    CostCenter_7Char = el.UDAKunit,
                    PositionNumber = el.positionNbr,
                    PositionSlotId = 0,
                    JobClassId = el.jobClassCode.Replace("-", ""),
                    JobClassFullDisplayCd = string.Empty,
                    JobTitle = string.Empty,
                    SalaryGradeCd = string.Empty,
                    FTE_percent = el.FTEpercent / 100,

                    EmployeeId = el.employeeID,
                    EmployeeName = String.Empty,

                    PositionEffDate = el.positionEffDate,
                    PositionEffDateNext = el.positionEffDateNext,
                    PositionBeginDate = el.positionBeginDate,
                    PositionEndDate = el.positionEndDate,
                    DirectLeaderID = string.Empty,
                    DirectLeaderName = string.Empty,
                    DirectLeaderNetID = string.Empty,
                    FLSAstatusCode = el.FLSAstatusCode,
                    FLSAstatusDesc = el.FLSAstatusDesc,
                    EmploymentTypeCode = el.employmentTypeCode,
                    EmploymentTypeDesc = el.employmentTypeDesc,
                    IsOverloaded = false,
                };
                positionSlots[el.positionNbr] = psd;
            }
            Assignment newAssignment = new Assignment
            {
                PvID = el.employeeID,
                AssignBeginDate = el.assignBeginDate,
                AssignEndDate = el.assignEndDate,
                AssignEffDate = el.assignEffDate,
                AssignEffDateNext = el.assignEffDateNext,

            };

            PositionSlotDetail thePSD = positionSlots[el.positionNbr];
            thePSD.Assignments.Add(newAssignment);


            if (thePSD.Assignments.Any(assignment => Regex.IsMatch(assignment.PvID, @"^\d+$")))
            {
                thePSD.Status = "FILLED";
                if (thePSD.Assignments.Where(assignment => Regex.IsMatch(assignment.PvID, @"^\d+$")).Count() > 1)
                {
                    thePSD.IsOverloaded = true;
                }

            }
            else
            {
                thePSD.Status = "VACANT";
            }


        }

        var output = new PositionSlots(positionSlots.Values.ToList());
        return output;

    }

... }

PositionSlots类:

public class PositionSlots
{
    //Constructor
    public PositionSlots(ICollection<PositionSlotDetail> pslist)
    {
        Positions = pslist;
    }

    //properites
    public ICollection<PositionSlotDetail> Positions { get; }

    private bool DetailsUpdated { get; set; } = false;

    public IEnumerable<PositionSlotDetail> PositionsCurrentAndActive
    {
        get
        {
            return from position in Positions
                   where position.PositionSlotId > 0 && position.PositionEndDate >= DateTime.Today
                   select position;

        }
    }

    public IEnumerable<PositionSlotDetail> PositionsNotFoundInPositionControl
    {
        get
        {
            return from position in Positions
                   where position.PositionSlotId == 0
                   select position;
        }
    }


    public IEnumerable<PositionSlotDetail> PositionsClosed
    {
        get
        {
            return from psd in Positions
                   where psd.PositionEndDate < DateTime.Today
                   && psd.PositionSlotId > 0
                   select psd;

        }
    }

    public decimal ActualFTETotal
    {
        get
        {
            return (from position in PositionsCurrentAndActive
                    from assignment in position.Assignments
                    where position.Assignments.Count() >= 1 && (!assignment.PvID.Equals("VACANT"))
                    select position.FTE_percent).Sum();


        }
    }

    public int FilledTotal
    {
        get
        {
            return PositionsCurrentAndActive.Where(x => x.Status == "FILLED").Count();
        }
    }

    public int VacantTotal
    {
        get
        {
            return PositionsCurrentAndActive.Where(x => x.Status == "VACANT").Count();
        }
    }

    public int OverloadedTotal
    {
        get
        {
            return PositionsCurrentAndActive.Where(x => x.IsOverloaded).Count();
        }
    }

    //methods


    public void UpdateDetails(PositionControlContext db)
    {
        if (!DetailsUpdated)
        {
            UpdateJobClassificationInfo(db);
            UpdateEmployeeName(db);
            UpdatePositionSlotId(db);  //if not found, PositionSlotId = 0
                                       //UpdateIsBudgeted(db);
            UpdateDirectLeader(db);
            DetailsUpdated = true;
        }
        else
        {
            return;
        }
    }

    private void UpdateJobClassificationInfo(PositionControlContext db)
    {
        string[] jobClassIds = (from x in Positions select x.JobClassId).Distinct().ToArray();

        var JobClassList = (from jc in db.JobClassifications where jobClassIds.Contains(jc.JobClassId) select jc).ToDictionary(jc => jc.JobClassId, jc => jc, StringComparer.OrdinalIgnoreCase);

        foreach (PositionSlotDetail psd in Positions)
        {
            if (!string.IsNullOrWhiteSpace(psd.JobClassId) && !psd.JobClassId.Equals("MISSING"))
            {

                JobClassification jobClassification;
                if (JobClassList.TryGetValue(psd.JobClassId, out jobClassification))
                {
                    psd.JobClassFullDisplayCd = jobClassification.JobClassFullDisplayCd;
                    psd.JobTitle = jobClassification.JobTitle;
                    psd.SalaryGradeCd = jobClassification.SalaryGradeCd;


                }
                else
                {
                    psd.JobClassFullDisplayCd = ($"{psd.JobClassId} not found in view V_JobClassifications.");
                    psd.JobTitle = ($"{psd.JobClassId} not found in view V_JobClassifications.");
                    psd.SalaryGradeCd = "--";
                }

            }
            else
            {
                psd.JobClassFullDisplayCd = "MISSING";
                psd.JobTitle = "MISSING";

            }
        }
        return;
    }

    private void UpdateEmployeeName(PositionControlContext db)
    {

        string[] empIdsStr = (from position in Positions
                              from assignment in position.Assignments
                              where (!assignment.PvID.Equals("VACANT"))
                              select assignment.PvID).Distinct().ToArray();


        // Positions.SelectMany(x => x.Assignments).SelectMany(x => x.PvID).ToArray();

        //string[] empIdsStr = (from x in Positions where (!x.EmployeeId.Contains("VACANT")) select x.EmployeeId).Distinct().ToArray();
        //int[] empIdsInt = Array.ConvertAll(empIdsStr, int.Parse);

        var EmployeeList = (from emp in db.IdAM_personLU where empIdsStr.Contains(emp.pvID) select emp).ToDictionary(emp => emp.pvID,
                 emp => emp.EmployeeFullName, StringComparer.OrdinalIgnoreCase);

        EmployeeList["VACANT"] = "VACANT";

        foreach (PositionSlotDetail psd in Positions)
        {
            string empName;
            if (EmployeeList.TryGetValue(psd.EmployeeId, out empName))
            {
                psd.EmployeeName = empName;

            }
            else
            {
                psd.EmployeeName = ($"{psd.EmployeeId} not found in Employee table.");
            }


            foreach (Assignment emp in psd.Assignments)
            {
                string empName2;
                if (EmployeeList.TryGetValue(emp.PvID, out empName2))
                {
                    emp.EmpDisplayName = empName2;

                }
                else
                {
                    emp.EmpDisplayName = ($"{psd.EmployeeId} not found in Employee table.");
                }
            }
        }

        return;
    }


    private void UpdateDirectLeader(PositionControlContext db)
    {
        string[] empIdsStr = (from x in Positions where (!x.EmployeeId.Contains("VACANT")) select x.EmployeeId).Distinct().ToArray();
        //int[] empIdsInt = Array.ConvertAll(empIdsStr, int.Parse);

        Dictionary<string, IdAM_arborLU> DirectLeader = new Dictionary<string, IdAM_arborLU>();

        var EmployeeDirectLeaderList = (from emp in db.IdAM_arborLU where empIdsStr.Contains(emp.emp_pvID) select emp).ToDictionary(emp => emp.emp_pvID,
                 emp => emp, StringComparer.OrdinalIgnoreCase);



        foreach (PositionSlotDetail psd in Positions)
        {
            if (psd.EmployeeId != "VACANT")  //will just leave DirectLeaderId and DirectLeaderName as string.Empty
            {
                IdAM_arborLU supervisor;
                if (EmployeeDirectLeaderList.TryGetValue(psd.EmployeeId, out supervisor))
                {
                    psd.DirectLeaderName = supervisor.sup_name;
                    psd.DirectLeaderID = supervisor.sup_pvID;
                    psd.DirectLeaderNetID = supervisor.sup_netID;


                }
                else
                {
                    psd.DirectLeaderName = ($"{psd.EmployeeId} not found in Arbor table.");
                }
            }

            foreach (Assignment emp in psd.Assignments)
            {
                if (psd.EmployeeId != "VACANT")
                {
                    IdAM_arborLU supervisor2;
                    if (EmployeeDirectLeaderList.TryGetValue(psd.EmployeeId, out supervisor2))
                    {
                        emp.DirectLeaderName = supervisor2.sup_name;
                        emp.DirectLeaderID = supervisor2.sup_pvID;
                        emp.DirectLeaderNetID = supervisor2.sup_netID;

                    }
                    else
                    {
                        emp.DirectLeaderName = ($"{psd.EmployeeId} not found in Arbor table.");
                        emp.DirectLeaderID = "--";
                        emp.DirectLeaderNetID = "--";
                    }
                }
            }
        }

        return;
    }

    private void UpdatePositionSlotId(PositionControlContext db)
    {
        string[] posnumber = (from x in Positions
                              select x.PositionNumber).ToArray();

        var slots = (from ps1 in db.PositionSlots
                     where posnumber.Contains(ps1.PositionNumber)
                     select ps1).ToDictionary(ps => ps.PositionNumber.Trim(), ps => ps.PositionSlotId, StringComparer.OrdinalIgnoreCase);

        foreach (PositionSlotDetail psd in Positions)
        {

            int posSlotId = 0;
            if (slots.TryGetValue(psd.PositionNumber, out posSlotId))
            {
                psd.PositionSlotId = posSlotId;
            }
        }
        return;
    }

    private void UpdateIsBudgeted(PositionControlContext db)
    {
        string[] posnumber = (from x in Positions
                              select x.PositionNumber).ToArray();

        var slots = (from ps1 in db.PositionSlots
                     where posnumber.Contains(ps1.PositionNumber)
                     select ps1).ToDictionary(ps => ps.PositionNumber.Trim(), ps => ps.IsBudgeted, StringComparer.OrdinalIgnoreCase);

        foreach (PositionSlotDetail psd in Positions)
        {

            bool isbudgeted = false;
            if (slots.TryGetValue(psd.PositionNumber, out isbudgeted))
            {
                psd.IsBudgeted = isbudgeted;
            }
        }
        return;
    }


}

1 个答案:

答案 0 :(得分:0)

您可以通过编写一个方法来实现:

IDMSElement.ToPositionSlot(db)

,然后按如下所示使用它:

PositionSlots myslots = elements.Select(x => x.ToPositionSlot(db))