ef4 запись, вставка, вставка, вставка - PullRequest
1 голос
/ 24 августа 2010

Есть ли способ пройти через все новые / измененные объекты и установить их поля, вставленные, обновленные,

С помощью ObjectStateManager я могу получить список этих объектов, но не смог найти способ установки значений свойств объекта.

foreach (var item in db.ObjectStateManager.GetObjectStateEntries(EntityState.Added))
{
System.Data.Objects.DataClasses.EntityObject entity = (System.Data.Objects.DataClasses.EntityObject)(item.Entity);
// now how can I set its .inserted_at to DateTime.Now
}

вот мое текущее решение

public interface IUpdateTrack
{
    DateTime? updated_at { get; set; }
    Guid? updated_by { get; set; }
}
public interface IInsertTrack
{
    DateTime? inserted_at { get; set; }
    Guid? inserted_by { get; set; }
}

реализовать интерфейс в частичном классе

public partial class crm_customer : BaseDB.IInsertTrack, BaseDB.IUpdateTrack

в классе хранилища

public void Save()
{
    foreach (var item in db.ObjectStateManager.GetObjectStateEntries(EntityState.Added))
    {
        System.Data.Objects.DataClasses.EntityObject entity = (System.Data.Objects.DataClasses.EntityObject)(item.Entity);
        if (item.Entity is BaseDB.IInsertTrack)
        {
            IInsertTrack insert_track = (IInsertTrack)(item.Entity);
            insert_track.inserted_at = DateTime.Now;
            insert_track.inserted_by = BaseDB.SessionContext.Current.ActiveUser.UserUid;
        }
    }
    foreach (var item in db.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
    {
        if (item.Entity is BaseDB.IUpdateTrack)
        {
            IUpdateTrack update_track = (IUpdateTrack)(item.Entity);
            update_track.updated_at = DateTime.Now;
            update_track.updated_by = BaseDB.SessionContext.Current.ActiveUser.UserUid;
        }
    }

Мне бы хотелось решение, которое не требует реализации интерфейса для каждого класса в модели, оно подвержено ошибкам, вы можете забыть реализовать этот интерфейс для некоторых классов. Я использую EF4, используя подход базы данных.

1 Ответ

1 голос
/ 24 августа 2010

Да, есть отличный способ сделать это в Entity Framework 4.0, спасибо Джулии Лерман за указание на этот хороший трюк


using System.Data.Common;
using System.Data.Metadata.Edm;
...</p>

<p>var entries = from e in db.ObjectStateManager.GetObjectStateEntries(
        EntityState.Added | EntityState.Modified)
              where e.Entity != null 
              select e;</p>

<p>foreach (var entry in entries) {<br>
    var fieldMetaData = entry.CurrentValues.DataRecordInfo.FieldMetadata;
    FieldMetadata updatedAtField = fieldMetaData
        .Where(f => f.FieldType.Name == "updated_at").FirstOrDefault();</p>

<pre><code>    if (updatedAtField.FieldType != null) {
       string fieldTypeName = updatedAtField.FieldType.TypeUsage.EdmType.Name;

        if (fieldTypeName == PrimitiveTypeKind.DateTime.ToString()) {
            entry.CurrentValues.SetDateTime(updatedAtField.Ordinal, 
                                            DateTime.Now);
        }
    }

}
Затем вы можете вызвать этот код из события SavingChanges, чтобы убедиться, что любой Поле updated_at автоматически обновляется.

Кстати, пространство имен System.Data.Metadata.Edm дает вам доступ к класс PrimitiveTypeKind.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...