覆盖SaveChanges以实现业务规则

时间:2014-05-20 12:47:57

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

我创建了一个工作解决方案,它覆盖了SaveChanges(),但想知道是否有更好,更清晰的方法来执行此操作。我真的不喜欢switch语句。下面,我已经描述了问题并说明了我的完整解决方案。

由于

问题 每当用户执行插入,更新或删除部分数据的操作时,这些数据分布在多个表中, 更新列NewClub.LastActivityDate = DateTime.Now

模特

public  class NewClub
{
 //Primary Key
 public int Id { get; set; }
 [...]
 public DateTime  LastActivityDate { get; set; }
}

 public class NewClubProspect
 {
   //Primary Key
   [Key]
   public int Id { get; set; }
   //Foreign Key
   public int NewClubId { get; set; }
   [..]
    public virtual NewClub NewClub { get; set; }
}

 public class NewClubCounselor
 {
     [Key]
      public int Id { get; set; }
     //Foreign Key
     public int NewClubId { get; set; }
    [...]
     public NewClub NewClub { get; set; }
}

// Several more model classes like these ...

解决方案

 public class MyContext : DbContext
    {
        public override int SaveChanges()
        {
            var entityInfoStr = String.Empty;
            var saveSuccess = false;
            var newClubPrimaryKeyId = 0;

            ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext;

            List<ObjectStateEntry> objectStateEntryList =
            ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added
                                                      | EntityState.Unchanged
                                                      | EntityState.Modified
                                                      | EntityState.Deleted).ToList();

            foreach (ObjectStateEntry entry in objectStateEntryList)
            {
                //Skip over relationships
                if (entry.IsRelationship) continue;

                //Make sure the entity is a member of the schema: NewClub[...]
                if (SecurityHelper.IsValidNewClubTableName(entry.EntitySet.Name))
                {

                    switch (entry.EntitySet.Name)
                    {
                        case "NewClubs":
                            var nc = entry.Entity as NewClub;
                            if (nc != null) { newClubPrimaryKeyId = nc.Id; }
                            break;

                        case "NewClubBuilders":
                            var ncb = entry.Entity as NewClubBuilder;
                            if (ncb != null) { newClubPrimaryKeyId = ncb.NewClubId; }
                            break;

                        case "NewClubCaseAnswers":
                            var ncca = entry.Entity as NewClubCaseAnswer;
                            if (ncca != null) { newClubPrimaryKeyId = ncca.NewClubId; }
                            break;

                        case "NewClubCommunityLeaders":
                            var nccl = entry.Entity as NewClubCommunityLeader;
                            if (nccl != null) { newClubPrimaryKeyId = nccl.NewClubId; }
                            break;

                        case "NewClubCounselors":
                            var ncc = entry.Entity as NewClubCounselor;
                            if (ncc != null) { newClubPrimaryKeyId = ncc.NewClubId; }
                            break;

                        case "NewClubEmails":
                            var nce = entry.Entity as NewClubEmail;
                            if (nce != null) { newClubPrimaryKeyId = nce.NewClubId; }
                            break;

                        case "NewClubKitOrders":
                            var ncko = entry.Entity as NewClubKitOrder;
                            if (ncko != null) { newClubPrimaryKeyId = ncko.NewClubId; }
                            break;

                        case "NewClubOrganizationChecklists":
                            var ncoc = entry.Entity as NewClubKitOrder;
                            if (ncoc != null) { newClubPrimaryKeyId = ncoc.NewClubId; }
                            break;                       

                        case "NewClubProspects":
                            var ncp = entry.Entity as NewClubProspect;
                            if (ncp != null) { newClubPrimaryKeyId = ncp.NewClubId; }
                            break;

                        case "NewClubRecruiterTrainingSchedules":
                            var ncrts = entry.Entity as NewClubRecruiterTrainingSchedule;
                            if (ncrts != null) { newClubPrimaryKeyId = ncrts.NewClubId; }
                            break;

                        case "NewClubRecruitingMember":
                            var ncrm = entry.Entity as NewClubRecruitingMember;
                            if (ncrm != null) { newClubPrimaryKeyId = ncrm.NewClubId; }
                            break;

                        case "NewClubRecruitingTeamEvent":
                            var ncrte = entry.Entity as NewClubRecruitingTeamEvent;
                            if (ncrte != null) { newClubPrimaryKeyId = ncrte.NewClubId; }
                            break;

                        case "NewClubSponsor":
                            var ncs = entry.Entity as NewClubSponsor;
                            if (ncs != null) { newClubPrimaryKeyId = ncs.NewClubId; }
                            break;
                    }

                    //Update the NewClub.LastActivityDate column
                    if (newClubPrimaryKeyId > 0)
                    {
                        string q = @"UPDATE NewClub SET LastActivityDate='" + DateTime.Now + "' WHERE Id="+newClubPrimaryKeyId;


                        using (var context = new MyContext())
                        {
                             var result = context.Database.ExecuteSqlCommand(q);
                        }


                    }


                }
            }

            try
            {

                 saveSuccess = base.SaveChanges() > 0;

            }
            catch (Exception e)
            {
                string ex = e.ToString();
                //Handle exception

            }

            return saveSuccess ? 1 : 0; 
        }
}

1 个答案:

答案 0 :(得分:2)

首先,为此目的处理ObjectContext.SavingChanges事件。它通常用于在将新值写入数据库之前验证已更改的对象。

其次,在您的情况下,使用所需的操作集IClub定义一个界面,例如GetClubId()。以您需要的方式实现您需要的每个实体的接口。这将让您检查接口实现:

foreach (ObjectStateEntry entry in objectStateEntryList)
{
    IClub club = entry.Entity as IClub;
    if (!entry.IsRelationship && club!=null)
    {
          newClubPrimaryKeyId = club.GetClubId();
          ...
    }
}

PS。接口实现可以在实体的部分类中完成,如果先使用数据库,也可以调整t4模板。


如果要更新多个实体,ObjectContext.Database.ExecuteSqlCommand也很方便,以便不先查询所有实体。在您的情况下,您正在更新单个项目,因此您可以先查询一个

var club = context.NewClub.FirstOrDefault(c => c.Id == newClubPrimaryKeyId);

然后更新它。

if (club!=null)
{
    club.LastActivityDate = DateTime.Now;
}