в Entity Framework, как вызвать метод на Entity перед сохранением - PullRequest
12 голосов
/ 13 июля 2011

Ниже я создал демонстрационную сущность, чтобы продемонстрировать, что я ищу:

public class User :  IValidatableObject
{
    public string Name { get; set; }

    [Required]
    public DateTime CreationDate { get; set; }

    public DateTime UpdatedOnDate { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if(Name = "abc")
        {
            yield return new ValidationResult("please choose any other name then abc", new[] { "Name" });
        }
    }
}

Я реализую интерфейс IValidatableObject, чтобы сделать эту сущность SelfValidating.

Сейчас в настоящее времясоздать нового пользователя iam, выполнив это

User u = new User();
u.Name = "Some name";
u.CreationDate = DateTime.Now
dbContext.Users.Add(u);
dbContext.SaveChanges();

Iam планирует переместить u.CreationDate=DateTime.Now; код внутри User класса.И реализовать интерфейс, который предоставляет метод, который будет выполняться перед сохранением и после проверки

// class structure that I am looking for
public class User : IValidatableObject,IMyCustomInterFace
{
    //rest codes as above class

    public void MyMethod(Whatever)
    {
        //this method gets called after Validate() and before save

        if(dataContext.Entry<User>(this).State == System.Data.EntityState.Added)
        {
            //add creation date_time
            this.CreationDate=DateTime.Now;

            //SET MORE DEFAULTS
        }

        if(dataContext.Entry<User>(this).State == System.Data.EntityState.Modified)
        {
            //update Updation time
            this.UpdatedOnDate = DateTime.Now;
        }
    }
}

, чтобы создать нового пользователя. Я просто должен сделать, как показано ниже, обратите внимание, что я не добавил свойство date в этомвремя, класс делает это автоматически.

User u = new User();
u.Name = "Some name";
dbContext.Users.Add(u);
dbContext.SaveChanges();

Чтобы обновить пользователя, свойство UpdatedOnDate будет автоматически обновлено классом

User u = getUserFromSomeWhere();
u.Name = "Updated Name";
dataContext.Entry<User>(u).State = System.Data.EntityState.Modified;
dbContext.SaveChanges();

Мой вопрос : естьлюбой существующий интерфейс, который предоставляет некоторый метод, который вызывается до Save и AfterValidate, или некоторые другие способы сделать это, о которых я, возможно, не знаю.

Или, если я создаю свой пользовательский интерфейс, как можноЯ делаю его метод для выполнения в порядке, который я хочу.

1 Ответ

23 голосов
/ 13 июля 2011

У меня почти идентичная ситуация, и я управляю ею, обрабатывая событие SavingChanges в контексте.

Сначала я создаю интерфейс, который определяет операции с метками времени:

public interface IHasTimeStamp
{
    void DoTimeStamp();
}

Затем я реализую этот интерфейс в моих сущностях:

Public class User : IHasTimeStamp
(
    public void DoTimeStamp()
    {
        if(dataContext.Entry<User>(this).State == System.Data.EntityState.Added)        
        {            
            //add creation date_time            
            this.CreationDate=DateTime.Now;            
        }        

        if(dataContext.Entry<User>(this).State == System.Data.EntityState.Modified)        
        {            
            //update Updation time            
            this.UpdatedOnDate=DateTime.Now;        
        }
    }
}

Последний шаг - зарегистрировать обработчик SavingChanges и реализовать его.

public partial class MyEntities
{
    partial void OnContextCreated()
    {
        // Register the handler for the SavingChanges event.
        this.SavingChanges
            += new EventHandler(context_SavingChanges);
    }

    // SavingChanges event handler.
    private static void context_SavingChanges(object sender, EventArgs e)
    {
        // Validate the state of each entity in the context
        // before SaveChanges can succeed.
        foreach (ObjectStateEntry entry in
            ((ObjectContext)sender).ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
        {
            if (!entry.IsRelationship && (entry.Entity is IHasTimeStamp))
            {
                (entry.Entity as IHasTimeStamp).DoTimeStamp();
            }
        }
    }
}
...