实体框架将替换新添加的记录,并在action方法内创建记录

时间:2015-02-20 22:50:41

标签: asp.net-mvc entity-framework asp.net-mvc-5 entity-framework-6 modelstate

我想实现这个简单的场景,我虽然EF支持开箱即用。 我有一个名为(技能)的父记录,我正在添加名为(LinktoKB)的子记录。现在添加一个新的LinktoKB后,我想返回一个包含最新LinkToKBs列表的视图(包含新添加的一个)。 现在我添加新LinktoKB的Post动作方法是: -

[HttpPost]
[ValidateAntiForgeryToken]
[CheckUserPermissions(Action = "Edit", Model = "Skill")]
public async Task<ActionResult> AddKBLink(AssignKBLinksToSkill assignkblinkToSkill)
{          
    try
    {

        if (assignkblinkToSkill.LinkToKB == null)
        {
            return HttpNotFound();
        }
        if (ModelState.IsValid)
        {
            unitofwork.SkillRepository.AddKBLinkToSkill(assignkblinkToSkill, unitofwork.StaffRepository.GetLoginUserName(User.Identity.Name));
            await unitofwork.Save();

            //i have removed the values from the model state to prevent showing validation error "that the URL and name is required after succfully adding a new link"
            // also to show the modified values and not the binded values

            string   oldlinkURL = assignkblinkToSkill.LinkToKB.URL;

            ModelState.Clear();

            var skillAfterAddingKBLink = await unitofwork.SkillRepository.FindSkill(assignkblinkToSkill.Skillid, r => r.LinkToKBs);
            assignkblinkToSkill.LinktoKBList = skillAfterAddingKBLink.LinkToKBs.ToList(); //get the new lsit from DB after addign the new link
            assignkblinkToSkill.LinkToKB.URL = "http://";//reset the values , so that user will not get old vlues
            assignkblinkToSkill.LinkToKB.Name = String.Empty;

            if (Request.IsAjaxRequest())
            {
                TempData["Partialmessage"] = string.Format("{0} URL have been Added", oldlinkURL);


                return PartialView("AddKBLink", assignkblinkToSkill);
            }
            TempData["message"] = string.Format("{0} URL have been Added", oldlinkURL);

            return View("AddKBLink", assignkblinkToSkill);
        }
    }

我的存储库方法是: -

public async Task<Skill> FindSkill(int id, params Expression<Func<Skill, object>>[] includeProperties)    
{
    var query = context.Skills.AsQueryable();
    if (includeProperties != null || includeProperties.Count() != 0 || includeProperties[0].Name == "0")
        query = includeProperties.Aggregate(query, (current, include) => current.Include(include));
    return await query.SingleOrDefaultAsync(a => a.SkillID == id);
}

&安培;

public void AddKBLinkToSkill(AssignKBLinksToSkill assignKBLinkToSkill,string username)
{
    var skill = context.Skills.SingleOrDefault(a=>a.SkillID == assignKBLinkToSkill.Skillid);
    skill.LinkToKBs.Add(assignKBLinkToSkill.LinkToKB);
    skill.Modified = System.DateTime.Now;

    skill.ModifiedBy = staffrepo.GetUserIdByUserName(username);

    context.Entry(skill).State = EntityState.Modified;
}

目前我得到一个非常奇怪的行为是,返回到视图的列表将不包含新添加的LinkToKB值,它将被以下值替换: -

assignkblinkToSkill.LinkToKB.URL = "http://"

所以有人可以就此提出建议,虽然我明确地从数据库中检索LinkToKB列表吗?

视觉工作室将如何在以下两个不同阶段: -

首先,这是新添加的LinkToKB: -

enter image description here

第二个EF已将其替换为action方法中的值: -

enter image description here

我花了一整天时间试图了解发生了什么......如果我删除了这些行: -

assignkblinkToSkill.LinkToKB.URL = "http://";//reset the values , so that user will not get old vlues
            assignkblinkToSkill.LinkToKB.Name = String.Empty;

我将正确获取新的最新列表(但我需要它们)..

我有两个模型类(Skill&amp; LinktoKB): -

public partial class Skill
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Skill()
        {
            this.SkillLevels = new HashSet<SkillLevel>();
            this.SkillLevelStaffs = new HashSet<SkillLevelStaff>();
            this.Customers = new HashSet<Customer>();
            this.LinkToKBs = new HashSet<LinkToKB>();
            this.SkillVersionHistories = new HashSet<SkillVersionHistory>();
            this.Skill1 = new HashSet<Skill>();
            this.Skills = new HashSet<Skill>();
        }

        public int SkillID { get; set; }
        public string Name { get; set; }
       //code goes here 


        public virtual SkillStatu SkillStatu { get; set; }
        public virtual SkillType SkillType { get; set; }

        public virtual ICollection<LinkToKB> LinkToKBs { get; set; }

    }

{

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public LinkToKB()
    {
        this.Skills = new HashSet<Skill>();
    }

    public int LinkToKBID { get; set; }
    public string URL { get; set; }
    public string Name { get; set; }

   public virtual ICollection<Skill> Skills { get; set; }
}

和以下viewModel类: -

 public class AssignKBLinksToSkill
    {
     public ICollection<LinkToKB> LinktoKBList { set; get; }
     public LinkToKB LinkToKB { set; get; }
     public int Skillid { set; get; }

    }

1 个答案:

答案 0 :(得分:1)

在您的代码中,始终只有一个assignkblinkToSkill.LinkToKB实例。当它进入方法时,它有一些存储在数据库中的值。稍后您将其值重新指定为"http://"

但这仍然是您添加到列表skillAfterAddingKBLink.LinkToKBs的实例!

您只需在视图模型中创建一个新实例:

assignkblinkToSkill.LinkToKB = new LinkToKB();
assignkblinkToSkill.LinkToKB.URL = "http://";