实体尝试在列中插入列表中的每个项目

时间:2015-02-06 15:48:10

标签: c# asp.net-mvc entity-framework entity

我有几个关联的对象,我试图插入到具有实体框架的几个表中,并且实体正在尝试将列表中的所有项自动插入到几个不同的(不存在的)列中。

问题在于属性public List<ApprovalStage> Stages,哪个实体会抛出此错误:

{"An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details."}

内部例外是:

{"Invalid column name 'ApprovalStage_Id'.\r\nInvalid column name 'ApprovalStage_Id1'.\r\nInvalid column name 'ApprovalStage_Id2'."}

我减少了列表中的对象数量,并重试以确认它确实试图将列表中的每个项目插入到自己的列中。

以下是有问题的对象:

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

    public List<ApprovalStage> Stages { get; set; }

    [ForeignKey("Form")]
    public long FormId { 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;
    }

    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.Approvers = new List<Approver>();
        InitialReview.Advisors = new List<Approver>();
        InitialReview.Viewers = new List<Approver>();

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

        //ApprovalStage MiddleApproval = new ApprovalStage();
        //MiddleApproval.Approvers = new List<Approver>();
        //MiddleApproval.Advisors = new List<Approver>();
        //MiddleApproval.Viewers = new List<Approver>();

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


        ApprovalStage FinalApproval = new ApprovalStage();
        FinalApproval.Approvers = new List<Approver>();
        FinalApproval.Advisors = new List<Approver>();
        FinalApproval.Viewers = new List<Approver>();

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

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

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

        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())
            {
                db.ComplexApprovalProcesses.Add(this);
                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; }

    public ComplexApprovalProcess ApprovalProcess { get; set; }

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

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

    public List<Approver> 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 void Approve()
    {
        this.Completed = true;
        this.Approved = true;
        //just to make sure
        this.Denied = false;
    }

    public void Deny()
    {
        this.Completed = true;
        this.Denied = true;
        //just to make sure
        this.Approved = false;
    }

    public bool Completed { get; set; }

    public bool Approved { get; set; }

    public bool Denied { get; set; }

    public bool CanAbstain { get; set; }

    public ApprovalStage()
    { 
        //just set some defaults, like approval stages should not be complete when constructed
        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 StageId { get; set; }

    public ApprovalStage Stage { get; set; }

    public bool Approved { get; set; }

    public bool Denied { get; set; }

    public bool Abstain { get; set; }

    private void checkCompletion() 
    {
        bool allApproved = true;

        bool oneDenied = false;

        foreach (Approver approver in this.Stage.Approvers)
        {
            if (!approver.Approved)
            {
                allApproved = false;
            }
            if (approver.Denied)
            {
                oneDenied = true;
            }
        }

        if (allApproved)
        {
            this.Stage.Approve();
        }
        if (oneDenied)
        {
            this.Stage.Deny();
        }
        else
        { 
            //outcome still uncertain, do nothing
        }
    }

    public void Approve()
    {
        this.Approved = true;
        this.Denied = false;

        checkCompletion();
    }

    public void Deny()
    {
        this.Denied = true;
        this.Approved = false;

        checkCompletion();
    }

    public Approver() { }

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

似乎实体并不理解List<ApprovalStage> Stages中的对象会引用ComplexApprovalProcess,而ComplexApprovalProcess并不需要提及ApprovalStages

编辑:如果有人可以腾出时间,真的需要帮助!感谢

1 个答案:

答案 0 :(得分:0)

嗯,我从来没有解决过这个问题,但是我把每个对象分开并用Ids分开保存,而不是让实体去做。