He enfrentado situaciones en las que necesito tener EF readonly property en caso de 'actualización optimista' (no carga el estado actual de su dominio desde la base de datos para verificar qué propiedades realmente han cambiado. Simplemente establece su objeto como Modificado y lo actualiza a la base de datos. En este caso, evita las operaciones redundantes de selección y fusión.Propiedades de solo lectura en EF 4.1
No puede escribir algo como esto: DataContext.Entry(entity).Property(propertyName).IsModified = false;
, porque el valor 'falso' no es compatible y obtendrá una excepción. (en EF 4.1)
He creado una estructura simple para registrar propiedades de solo lectura en el repositorio. Por lo tanto, puede facilitar la modificación de propiedades que simplemente no son leales.
¿Qué opina sobre esto?
public abstract class RepositoryBase<T> where T : class
{
private const string MethodReferenceErrorFormat = "Expression '{0}' refers to a method, not a property.";
private const string FieldReferenceErrorFormat = "Expression '{0}' refers to a field, not a property.";
protected IList<PropertyInfo> _readOnlyProperties;
/// <summary>
/// This method is used to register readonly property for Entity.
/// </summary>
/// <param name="propertyLambda">Entity property as LambdaExpression</param>
protected void RegisterReadOnlyProperty<TProperty>(Expression<Func<T, TProperty>> propertyLambda)
{
Guard.ArgumentNotNull(propertyLambda, "propertyLambda");
var propertyMember = propertyLambda.Body as MemberExpression;
if (propertyMember == null)
{
var exceptionMessage = string.Format(MethodReferenceErrorFormat, propertyLambda);
throw new ArgumentException(exceptionMessage);
}
var propertyInfo = propertyMember.Member as PropertyInfo;
if (propertyInfo == null)
{
var exceptionMessage = string.Format(FieldReferenceErrorFormat, propertyLambda);
throw new ArgumentException(exceptionMessage);
}
_readOnlyProperties.Add(propertyInfo);
}
/// <summary>
/// This method is used to attach domain object to DbContext and mark it as modified to save changes.
/// </summary>
/// <param name="entity">Detached entity</param>
public void SetModified(T entity)
{
Guard.ArgumentNotNull(entity, "entity");
//Mark whole entity as Modified, when collection of readonly properties is empty.
if(_readOnlyProperties.Count == 0)
{
DataContext.Entry(entity).State = EntityState.Modified;
return;
}
//Attach entity to DbContext.
_dbSet.Attach(entity);
//Mark all properties except readonly as Modified.
var allProperties = entity.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
var propertiesForUpdate = allProperties.Except(_readOnlyProperties);
foreach (var propertyInfo in propertiesForUpdate)
{
DataContext.Entry(entity).Property(propertyInfo.Name).IsModified = true;
}
}
Gracias! Tu versión se ve bien! – zonder
Cuando uso esto me da el siguiente error, No puedo convertir la expresión Lambda a Tipo 'Expresión> []' porque no es un tipo de delegado –