Заставить AddOrUpdate изменить только некоторые свойства
Это может быть простой вопрос, однако я новичок в Code First и Migrations, так что терпите меня. Я приведу пример кода к минимуму, чтобы показать проблему:
у меня естьBaseAuditableEntity
что включает в себя это (среди прочего, но давайте упростим):
public abstract class BaseAuditableEntity : BaseEntity, IAuditableEntity
{
public DateTime CreatedOn { get; set; }
public DateTime LastModified { get; set; }
}
Теперь (например)User
POCO наследует от него:
public class User : BaseAuditableEntity
{
public string UserName { get; set; }
public string PasswordHash { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public bool Active { get; set; }
public DateTime? LastLogin { get; set; }
}
У меня есть это в моем контекстеSaveChanges
метод, чтобы заполнитьCreatedOn
а такжеLastModified
даты (упрощенно):
public override int SaveChanges()
{
var changeSet = ChangeTracker.Entries<IAuditableEntity>();
if (changeSet != null)
{
foreach (var entry in changeSet.Where(p => p.State != EntityState.Unchanged))
{
var now = DateTime.UtcNow;
if (entry.State == EntityState.Added)
entry.Entity.CreatedOn = now;
entry.Entity.LastModified = now;
}
}
return base.SaveChanges();
}
И теперь у меня есть миграция, которая запускает некоторых пользователей, например:
protected override void Seed(MyContext context)
{
context.Users.AddOrUpdate(
p => p.UserName,
new User { Active = true,
FullName = "My user name",
UserName = "ThisUser",
PasswordHash = "",
Email = "my@email",
LastLogin = null,
}
// etc.
);
}
Теперь у меня есть проблема при посеве сAddOrUpdate
после миграции. Когда сущность новая (она добавляется),CreatedOn
заполняется правильно и все работает как положено. Однако, когда объект изменен (он уже существует в базе данных иUserName
соответствует), он пытается обновить его с помощью новой сущности, которую я создаю ... это не удается, потому чтоCreatedOn
имеет недействительныйDateTime
(в этом случае,DateTime.MinValue
).
Есть ли способ использоватьAddOrUpdate
метод, чтобы он фактически извлекал соответствующий объект из базы данных и просто обновлял поля не по умолчанию? Или, может быть, какой-то способ сказать, какие поля НЕ обновлять? Для этого конкретного случая я хотел быCreatedOn
поле должно быть неизменным, но общее решение будет оценено.
Может быть, я должен сделать свой собственныйAddOrUpdate
метод, который включает в себя предикат с полями, которые я хочу изменить, вместо того, чтобы передать ему совершенно новую сущность?
Это EF 6.1
ОбновитьЯ знаю, что могу легко решить это дляCreatedOn
дата, это то, что я сейчас делаю для этого конкретного случая:
foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged))
{
var now = DateTime.UtcNow;
if (entry.State == EntityState.Added)
{
entry.Entity.CreatedOn = now;
}
else
{
if (entry.Property(p => p.CreatedOn).CurrentValue == DateTime.MinValue)
{
var original = entry.Property(p => p.CreatedOn).OriginalValue;
entry.Property(p => p.CreatedOn).CurrentValue = original != SqlDateTime.MinValue ? original : now;
entry.Property(p => p.CreatedOn).IsModified = true;
}
}
entry.Entity.LastModified = now;
}
Я ищу более общее решение, хотя