2015-02-09 3 views
0

У меня есть объект, который должен иметь несколько списков другого объекта. Однако каждый из этих списков будет состоять из одного и того же типа, и это, похоже, путает структуру. Я прочитал этот вопрос:Как иметь несколько списков в объекте того же типа?

Multiple collections of same type in entity framework

и последовал предложение дифференцировать различные списки наследования различных типов для каждого из списков элементов. Это, кажется, ничего не делает.

Ошибки я получаю:

Exception:Thrown: "Invalid column name 'ApprovalStage_Id1'. Invalid column name 'ApprovalStage_Id2'. Invalid column name 'ApprovalStage_Id3'." (System.Data.SqlClient.SqlException) A System.Data.SqlClient.SqlException was thrown: "Invalid column name 'ApprovalStage_Id1'. Invalid column name 'ApprovalStage_Id2'. Invalid column name 'ApprovalStage_Id3'." Time: 2/9/2015 3:22:05 PM Thread:Worker Thread[11116]

А вот мои сущности. Это немного плотный, но в основном основной объект - ComplexApprovalProcess, который имеет некоторое количество ApprovalStages в одном списке (все в порядке). Проблема заключается в том, что каждый ApprovalStage имеет три списка: Approver, «Утверждающие», «Зрители» и «Советники». Когда Entity пытается сохранить эти сущности, он выдает ошибку выше. Как я уже сказал, я пробовал дифференцировать их, наследуя три других класса от Approver, так как вы можете видеть, что теперь они являются коллекциями ReqApprover, Advisor и Viewer, но он по-прежнему выдает ошибку выше, как и раньше. Любые идеи, почему Entity запутывается в этом? Каждый объект Approver должен иметь ссылку только на ApprovalStage, к которому принадлежит, но Entity кажется, что он должен ссылаться на три разных ApprovalStages и пытается динамически найти те столбцы, которых не существует. Благодарю.

ПРИМИТИВЫ:

public class ComplexApprovalProcess 
{ 
    [Key] 
    public long Id { get; set; } 

    [InverseProperty("ApprovalProcessId")] 
    public List<ApprovalStage> Stages { get; set; } 

    [ForeignKey("Form")] 
    public long FormId { get; set; } 

    public int CurrentStage { get; set; } 

    public FormBase Form { get; set; } 

    bool Approved { get; set; } 

    bool Denied { get; set; } 

    private bool CheckCompleted() { 

     foreach (ApprovalStage stage in this.Stages) 
     { 
      if (stage.Completed == false) 
      { 
       //if any stage is incomplete, the process is not complete 
       return false; 
      } 
     } 
     //no stages incomplete means all stages complete 
     return true; 
    } 

    private bool AdvanceStage() 
    { 
     //check the completion condition of the current stage, if completed, advance to next stage 
     ApprovalStage current = Stages.Where(m => m.StageOrder == this.CurrentStage).FirstOrDefault(); 

     if (current != null) 
     { 
      //check if stage is completed 
      if (current.CheckCompletion()) 
      { 
       //check if stage is approved 
       if (current.Approved) 
       { 
        //check if process contains additional stages 
        if (this.Stages.Count > this.CurrentStage) 
        { 
         //Move to next stage 
         this.CurrentStage += 1; 
         ApprovalStage next = Stages.Where(m => m.StageOrder == this.CurrentStage).FirstOrDefault(); 

         if (next != null) 
         { 
          next.StartStage(); 
         } 
         else 
         { 
          throw new Exception("Huh?"); 
         } 
        } 
       } 
      } 
     } 
     else 
     { 
      throw new Exception("Wut"); 
     } 
     return false; 
    } 

    public static ComplexApprovalProcess CreateCheckRequestApprovalProcess(FormBase form) 
    { 
     UsersModel user = null; 

     ComplexApprovalProcess process = new ComplexApprovalProcess(); 

     using (TechnologyProjectPlanContext db = new TechnologyProjectPlanContext()) 
     { 
      int id = SessionVar.Get<int>(SessionVar.USERID); 

      user = db.UsersModels.Where(m => m.Id == id).FirstOrDefault(); 
     } 

     process.Form = form; 

     ApprovalStage InitialReview = new ApprovalStage(); 
     InitialReview.StageOrder = 1; 
     InitialReview.Approvers = new List<ReqApprover>(); 
     InitialReview.Advisors = new List<Advisor>(); 
     InitialReview.Viewers = new List<Viewer>(); 
     InitialReview.Form = form; 

     InitialReview.ApprovalProcess = process; 
     InitialReview.Approvers.Add(new ReqApprover(user, form, InitialReview)); 
     InitialReview.Advisors.Add(new Advisor(user, form, InitialReview)); 
     InitialReview.Viewers.Add(new Viewer(user, form, InitialReview)); 
     InitialReview.StageName = "Initial Review"; 

     ApprovalStage MiddleApproval = new ApprovalStage(); 
     MiddleApproval.StageOrder = 2; 
     MiddleApproval.Approvers = new List<ReqApprover>(); 
     MiddleApproval.Advisors = new List<Advisor>(); 
     MiddleApproval.Viewers = new List<Viewer>(); 
     MiddleApproval.Form = form; 

     MiddleApproval.ApprovalProcess = process; 
     MiddleApproval.Approvers.Add(new ReqApprover(user, form, MiddleApproval)); 
     MiddleApproval.Advisors.Add(new Advisor(user, form, MiddleApproval)); 
     MiddleApproval.Viewers.Add(new Viewer(user, form, MiddleApproval)); 
     MiddleApproval.StageName = "Middle Approval"; 


     ApprovalStage FinalApproval = new ApprovalStage(); 
     FinalApproval.StageOrder = 3; 
     FinalApproval.Approvers = new List<ReqApprover>(); 
     FinalApproval.Advisors = new List<Advisor>(); 
     FinalApproval.Viewers = new List<Viewer>(); 
     FinalApproval.Form = form; 

     FinalApproval.ApprovalProcess = process; 
     FinalApproval.Approvers.Add(new ReqApprover(user, form, FinalApproval)); 
     FinalApproval.Advisors.Add(new Advisor(user, form, FinalApproval)); 
     FinalApproval.Viewers.Add(new Viewer(user, form, FinalApproval)); 
     FinalApproval.StageName = "Final Approval"; 

     process.Stages = new List<ApprovalStage>(); 
     process.Stages.AddRange(new ApprovalStage[] { InitialReview, MiddleApproval, FinalApproval }); 

     //set default values 
     process.Approved = false; 
     process.Denied = false; 

     process.CurrentStage = 1; 
     process.Stages[0].StartStage(); 
     return process; 
    } 

    public void SaveToDb() 
    { 
     //make sure we have at least one stage and either a form reference (new form) or form id (old form) before moving forward 
     if ((Stages != null && Stages.Count > 0) && (Form != null || FormId > 0)) 
     { 
      using (TechnologyProjectPlanContext db = new TechnologyProjectPlanContext()) 
      { 
       //first we have to save the process to get an Id 
       //copy stages out so we can save without the fuss 
       List<ApprovalStage> stages = this.Stages; 

       this.Stages = null; 

       db.ComplexApprovalProcesses.Add(this); 
       db.SaveChanges(); 

       //'this' now has an Id 

       //ok let's work it out from the bottom to the top, first separate out approvers from stages and save: 
       foreach (ApprovalStage stage in stages) 
       { 
        ICollection<ReqApprover> approvers = stage.Approvers; 
        ICollection<Advisor> advisors = stage.Advisors; 
        ICollection<Viewer> viewers = stage.Viewers; 

        stage.FormId = stage.Form.Id; 
        stage.Form = null; 

        stage.Approvers = null; 
        stage.Advisors = null; 
        stage.Viewers = null; 

        stage.ApprovalProcessId = this.Id; 

        db.ApprovalStages.Add(stage); 
        db.SaveChanges(); 

        //stage now has an id; 
        //iterate through each set of approvers and save 
        foreach (Approver approver in approvers) 
        { 
         approver.FormId = stage.FormId; 
         approver.UserId = approver.User.Id; 
         approver.ApprovalStage_Id = stage.Id; 

         approver.Form = null; 
         approver.User = null; 
         approver.Stage = null; 

         db.Approvers.Add(approver); 
         db.SaveChanges(); 
        } 

        foreach (Advisor approver in advisors) 
        { 
         approver.FormId = stage.FormId; 
         approver.UserId = approver.User.Id; 
         approver.ApprovalStage_Id = stage.Id; 

         approver.Form = null; 
         approver.User = null; 
         approver.Stage = null; 

         db.Approvers.Add(approver); 
        } 

        foreach (Viewer approver in viewers) 
        { 
         approver.FormId = stage.FormId; 
         approver.UserId = approver.User.Id; 
         approver.ApprovalStage_Id = stage.Id; 

         approver.Form = null; 
         approver.User = null; 
         approver.Stage = null; 

         db.Approvers.Add(approver); 
        } 
        db.SaveChanges(); 
       } 
      } 
     } 
    } 
} 

public class ApprovalStage 
{ 
    //Each stage requires at least one approver 
    [Key] 
    public long Id { get; set; } 

    [ForeignKey("ApprovalProcess")] 
    public long ApprovalProcessId { get; set; } 

    [ForeignKey("Form")] 
    public long FormId { get; set; } 

    public FormBase Form { get; set; } 

    public ComplexApprovalProcess ApprovalProcess { get; set; } 

    public ICollection<ReqApprover> Approvers { get; set; } //These users are required to approve before the form can move to the next stage. 

    public ICollection<Advisor> Advisors { get; set; } //These users can see the form and approve at this stage, but they are not required. 

    public ICollection<Viewer> Viewers { get; set; } //These users can see the form, but cannot approve 

    public string StageName { get; set; } //Name of stage e.g. Review, Final Approval, etc. Gives a custom feel? 

    public int StageOrder { get; set; } 

    public bool Completed { get; set; } 

    public bool Approved { get; set; } 

    public bool Denied { get; set; } 

    public bool CanAbstain { get; set; } 

    public ApprovalStage() 
    { 
     this.Approved = false; 
     this.Denied = false; 
     this.Completed = false; 
    } 
} 

public class Approver 
{ 
    [Key] 
    public long Id { get; set; } 

    [ForeignKey("User")] 
    public int UserId { get; set; } 

    public UsersModel User { get; set; } 

    [ForeignKey("Form")] 
    public long FormId { get; set; } 

    public FormBase Form { get; set; } 

    [ForeignKey("Stage")] 
    public long ApprovalStage_Id { get; set; } 

    public ApprovalStage Stage { get; set; } 

    public bool Approved { get; set; } 

    public bool Denied { get; set; } 

    public bool Abstain { get; set; } 

    public Approver() { } 

    public Approver(UsersModel user, FormBase form, ApprovalStage stage) 
    { 
     this.Stage = stage; 
     this.User = user; 
     this.Approved = false; 
     this.Denied = false; 
     this.Abstain = false; 
    } 
} 

ответ

0

Ok так я понял ошибку я делал. Я не думал о том, что после размещения в базе данных разные списки одного и того же типа объектов не знали бы, из какого списка они возникли. То есть, утверждающий, советник и просмотрщик будут выглядеть одинаково с каркасом после того, как они будут вставлены. Я продолжал сталкиваться с ошибками с наследованием утверждающих, поэтому я просто сделал 3 разных класса и таблицы и скопировал дизайн для каждого из них, и он отлично работает. Не могу поверить, что я потратил так много времени на это ...

Смежные вопросы