Skip to content

Commit

Permalink
Update version number
Browse files Browse the repository at this point in the history
Added Delta.GetSpecifiedPropertyNames and
Delta.GetNotSpecifiedPropertyNames methods.
Documentation comments translated to English.
Example project comments translated to English.
  • Loading branch information
omaxel committed Aug 8, 2017
1 parent 67b620e commit bb738b1
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 74 deletions.
50 changes: 23 additions & 27 deletions src/Examples/SimplePatch.WebAPI/Controllers/EFController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,57 +17,53 @@ public async Task<IEnumerable<PersonEF>> GetAll()
return await db.People.ToListAsync();
}

[HttpPatch]
public async Task<IHttpActionResult> PatchOne(int id, Delta<PersonEF> person)
{
//Determino l'entità da aggiornare in base al parametro id
var personToPatch = await db.People.FindAsync(id);
if (personToPatch == null) return BadRequest("Person not found");
[HttpPatch]
public async Task<IHttpActionResult> PatchOne(int id, Delta<PersonEF> person)
{
// Determines the entity to be updated according to the id parameter
var personToPatch = await db.People.FindAsync(id);
if (personToPatch == null) return BadRequest("Person not found");

/*
* Applico le modifiche specificate all'entità originale. Tuttavia, il parametro Id non viene mai aggiornato.
* Vedi Global.asax
*/
person.Patch(personToPatch);
db.Entry(personToPatch).State = EntityState.Modified;
// Apply the specified changes to the original entity. The Id property won't be changed. See why in Global.asax.
person.Patch(personToPatch);

//Adesso la variabile personToPatch è aggiornata
// Mark the entity as modified
db.Entry(personToPatch).State = EntityState.Modified;

//Salvo le modifiche
await db.SaveChangesAsync();
// Now the personToPatch variable is updated

return Ok(personToPatch);
}
// Save the changes
await db.SaveChangesAsync();

return Ok(personToPatch);
}

[HttpPatch]
public async Task<IHttpActionResult> PatchMultiple(DeltaCollection<PersonEF> people)
{
foreach (var person in people)
{
//Tento di ottenere il valore della proprietà Id
// Try to get the value of the Id property
if (person.TryGetPropertyValue(nameof(PersonEF.Id), out var id))
{
//Determino l'entità da aggiornare in base all'id specificato
// Determines the entity to be updated according to the id parameter
var personToPatch = await db.People.FindAsync(Convert.ToInt32(id));
if (personToPatch == null) return BadRequest("Person not found (Id = " + id + ")");

/*
* Applico le modifiche specificate all'entità originale. Tuttavia, il parametro Id non viene mai aggiornato.
* Vedi Global.asax
*/

// Apply the specified changes to the original entity
person.Patch(personToPatch);

//Contrassegno l'entità come modificata
// Mark the entity as modified
db.Entry(personToPatch).State = EntityState.Modified;
}
else
{
//La proprietà Id non è stata specificata per la persona rappresentata dalla variabile person
// The Id property was not specified for the person represented by the person variable
return BadRequest("Id property not found for a person");
}
}

//Salvo le modifiche
// Save the changes
await db.SaveChangesAsync();

return Ok(await db.People.ToListAsync());
Expand Down
25 changes: 11 additions & 14 deletions src/Examples/SimplePatch.WebAPI/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ public IEnumerable<Person> GetAll()
[HttpPatch]
public IHttpActionResult PatchOne(int id, Delta<Person> person)
{
//Determino l'entità da aggiornare in base al parametro id
// Determines the entity to be updated according to the id parameter
var personToPatch = TestData.People.FirstOrDefault(x => x.Id == id);
if (personToPatch == null) return BadRequest("Person not found");

/*
* Applico le modifiche specificate all'entità originale. Tuttavia, il parametro Id non viene mai aggiornato.
* Vedi Global.asax
*/
var c = person.GetSpecifiedPropertyNames();

if (personToPatch == null) return BadRequest("Person not found");

// Apply the changes specified to the original entity
person.Patch(personToPatch);

//Adesso la variabile personToPatch è aggiornata
// Now the personToPatch variable is updated

return Ok(personToPatch);
}
Expand All @@ -37,22 +37,19 @@ public IHttpActionResult PatchMultiple(DeltaCollection<Person> people)
{
foreach (var person in people)
{
//Tento di ottenere il valore della proprietà Id
// Try to get the value of the Id property
if (person.TryGetPropertyValue(nameof(Person.Id), out var id))
{
//Determino l'entità da aggiornare in base all'id specificato
// Determines the entity to be updated according to the specified id
var entityToPatch = TestData.People.FirstOrDefault(x => x.Id == Convert.ToInt32(id));
if (entityToPatch == null) return BadRequest("Person not found (Id = " + id + ")");

/*
* Applico le modifiche specificate all'entità originale. Tuttavia, il parametro Id non viene mai aggiornato.
* Vedi Global.asax
*/
// Apply the specified changes to the original entity
person.Patch(entityToPatch);
}
else
{
//La proprietà Id non è stata specificata per la persona rappresentata dalla variabile person
// The Id property was not specified for the person represented by the person variable
return BadRequest("Id property not found for a person");
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Examples/SimplePatch.WebAPI/Global.asax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ protected void Application_Start()
GlobalConfiguration.Configure(WebApiConfig.Register);
DeltaConfig.Init((cfg) =>
{
// Id property will not be changed when calling the Patch method.
cfg.ExcludeProperties<Person>(x => x.Id);
});
}
Expand Down
90 changes: 59 additions & 31 deletions src/SimplePatch/Delta.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ namespace SimplePatch
{
public sealed class Delta<TEntity> : IDictionary<string, object> where TEntity : class, new()
{
/// <summary>
/// Contains the property-value pair for the <see cref="TEntity"/> entity.
/// </summary>
private Dictionary<string, object> dict = new Dictionary<string, object>();

/// <summary>
/// Il nome completo del tipo <see cref="TEntity"/>
/// The full name of the type <see cref="TEntity"/>.
/// </summary>
private string typeFullName;

Expand All @@ -32,40 +35,40 @@ public Delta() : base()
}

/// <summary>
/// Crea una nuova entità del tipo <see cref="TEntity"/> e popola le proprietà per cui si dispone un valore.
/// Create a new <see cref="TEntity" /> instance and fill the properties for which you have a value.
/// </summary>
/// <returns>Una nuova entità di tipo <see cref="TEntity"/></returns>
/// <returns>The <see cref="TEntity"/> instance</returns>
public TEntity GetEntity()
{
return SetPropertiesValue(new TEntity());
}

/// <summary>
/// Imposta il valore delle proprietà modificate per l'entità specificata.
/// Sets the value of the modified properties for the specified entity.
/// </summary>
/// <param name="entity">L'entità da modificare.</param>
/// <param name="entity">Entity to be edited.</param>
public void Patch(TEntity entity)
{
if (entity == null) throw new ArgumentNullException();
entity = SetPropertiesValue(entity);
}

/// <summary>
/// Indica se il nome della proprietà specificata è presente nella lista dei nomi delle proprietà modificate.
/// Indicates whether the specified property name is present in the list of changed property names.
/// </summary>
/// <param name="propertyName">Il nome della proprietà da verificare</param>
/// <returns>True se il nome della proprietà è presente nella lista dei nomi delle proprietà modificate, altrimenti False</returns>
/// <param name="propertyName">The name of the property to be verified.</param>
/// <returns>True if the property name is present in the list of changed property names, otherwise False.</returns>
public bool HasProperty(string propertyName)
{
return dict.ContainsKey(propertyName);
}

/// <summary>
/// Tenta di ottenere il valore della proprietà con nome specificato.
/// Try to get the property value with the specified name.
/// </summary>
/// <param name="propertyName">Il nome della proprietà per cui ottenere il valore.</param>
/// <param name="propertyValue">Il valore della proprietà specificata.</param>
/// <returns>True se è stato possibile ottenere il valore della proprietà, altrimenti False.</returns>
/// <param name="propertyName">The name of the property to get the value.</param>
/// <param name="propertyValue">The value of the specified property.</param>
/// <returns>True if it was possible to get the property value, otherwise False.</returns>
public bool TryGetPropertyValue(string propertyName, out object propertyValue)
{
if (!HasProperty(propertyName))
Expand All @@ -79,39 +82,62 @@ public bool TryGetPropertyValue(string propertyName, out object propertyValue)
}

/// <summary>
/// Aggiunge un elemento al dizionario solo se la chiave specificata è un nome di proprietà di <see cref="TEntity"/>.
/// Adds an element to the dictionary only if the specified key is a property name of <see cref="TEntity"/>.
/// </summary>
/// <param name="item">Elemento da aggiungere. Se <paramref name="item"/>.Value è null o <see cref="string.Empty"/> l'elemento non verrà aggiunto. Vedi <see cref="IsPropertyAllowed(string)".</param>
/// <param name="item">Item to be added. The element will not be added if <paramref name="item"/>.Value is null or it is equal to <see cref="string.Empty"/>. See <see cref="IsPropertyAllowed(string)".</param>
public void Add(KeyValuePair<string, object> item)
{
if (IsPropertyAllowed(item.Key)) dict.Add(item.Key, item.Value);
}

/// <summary>
/// Aggiunge la chiave e il valore specificati al dizionario solo se la chiave specificata è un nome di proprietà di <see cref="TEntity"/>.
/// Adds the specified key and value to the dictionary only if the specified key is a property name of <see cref="TEntity"/>.
/// </summary>
/// <param name="key">Chiave dell'elemento da aggiungere.</param>
/// <param name="value">Valore dell'elemento da aggiungere. Se null o <see cref="string.Empty"/> l'elemento non verrà aggiunto. Vedi <see cref="IsPropertyAllowed(string)"./></param>
/// <param name="key">Element key to add.</param>
/// <param name="value">Value of element to be added. The element will not be added if null or equal to <see cref="string.Empty"/>. See <see cref="IsPropertyAllowed(string)".</param>
public void Add(string key, object value)
{
if (IsPropertyAllowed(key)) dict.Add(key, value);
}

/// <summary>
/// Indica se <see cref="TEntity"/> espone una proprietà con il nome specificato.
/// Returns the properties that have been specified (compared to <see cref="TEntity"/> properties) as an enumeration of property names.
/// </summary>
/// <returns>The property names.</returns>
public IEnumerable<string> GetSpecifiedPropertyNames()
{
foreach (var item in dict)
{
yield return item.Key;
}
}

/// <summary>
/// Returns the properties that haven't been specified (compared to <see cref="TEntity"/> properties) as an enumeration of property names.
/// </summary>
/// <param name="propertyName">Il nome della proprietà da verificare.</param>
/// <returns>True se <see cref="TEntity"/> espone una proprietà con il nome specificato, altrimenti False</returns>
/// <returns>The property names.</returns>
public IEnumerable<string> GetNotSpecifiedPropertyNames()
{
return DeltaCache.entityProperties[typeFullName].Select(x => x.Name).Where(x => !dict.ContainsKey(x));
}

#region Private methods

/// <summary>
/// Indicates whether <see cref="TEntity" /> exposes a property with the specified name.
/// </summary>
/// <param name="propertyName">The name of the property to be verified.</param>
/// <returns>True if <see cref="TEntity" /> exposes a property with the specified name, otherwise False.</returns>
private bool IsPropertyAllowed(string propertyName)
{
return !string.IsNullOrEmpty(propertyName) && DeltaCache.entityProperties[typeFullName].Any(x => x.Name == propertyName);
}

/// <summary>
/// Imposta il valore per ogni proprietà di <see cref="TEntity"/> per cui esiste un riferimento in <see cref="dict"/>.
/// Set the value for each property of <see cref="TEntity" /> for which there is a reference in <see cref="dict" />.
/// </summary>
/// <param name="entity">L'istanza di <see cref="TEntity"/> per cui impostare le proprietà.</param>
/// <returns>L'entità modificata</returns>
/// <param name="entity">The instance of <see cref="TEntity" /> to set properties.</param>
/// <returns>The modified entity.</returns>
private TEntity SetPropertiesValue(TEntity entity)
{
//Se la cache non contiene la lista delle proprietà per il tipo specificato, aggiungo le proprietà
Expand All @@ -135,11 +161,11 @@ private TEntity SetPropertiesValue(TEntity entity)
}

/// <summary>
/// Indica se, per la proprietà con nome specificato appartenente all'entità specificata, deve essere disabilitata la modifica.
/// Specifies whether the change must be disabled for the property with specified name belonging to the specified entity.
/// </summary>
/// <param name="typeFullName">Il nome intero dell'entità che espone la proprietà.</param>
/// <param name="propertyName">Il nome della proprietà.</param>
/// <returns>True se la proprietà è esclusa dalle modifiche, altrimenti False.</returns>
/// <param name="typeFullName">The entity's full name that exposes the property.</param>
/// <param name="propertyName">The name of the property.</param>
/// <returns>True if property is excluded from changes, otherwise False.</returns>
private bool IsExcludedProperty(string typeFullName, string propertyName)
{
if (!DeltaCache.excludedProperties.ContainsKey(typeFullName)) return false;
Expand All @@ -148,16 +174,18 @@ private bool IsExcludedProperty(string typeFullName, string propertyName)
}

/// <summary>
/// Restituisce il tipo specificato dal parametro o il tipo sottostante se <paramref name="type"/> è <see cref="Nullable"/>.
/// Returns the type specified by the parameter or type below if <paramref name="type" /> is <see cref="Nullable" />.
/// </summary>
/// <param name="type">Il tipo da verificare.</param>
/// <returns>Il tipo specificato dal parametro o il tipo sottostante se <paramref name="type"/> è <see cref="Nullable"/>.</returns>
/// <param name="type">The type to be verified.</param>
/// <returns>The type specified by the parameter or type below if <paramref name="type" /> is <see cref="Nullable" />.</returns>
private Type GetTrueType(Type type)
{
return Nullable.GetUnderlyingType(type) ?? type;
}

#region Implementazione dell'interfaccia IDictionary
#endregion

#region Implementing the IDictionary Interface
public ICollection<string> Keys => dict.Keys;
public ICollection<object> Values => dict.Values;
public int Count => dict.Count;
Expand Down
4 changes: 2 additions & 2 deletions src/SimplePatch/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build
// usando l'asterisco '*' come illustrato di seguito:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]

0 comments on commit bb738b1

Please sign in to comment.