Skip to content

Transacciones con LinqToSQL

by en 1 febrero, 2012

Ya hace varias entradas vengo comentándoles de Linq y sus beneficios para el programador. Pero como saben, de la teoría a la práctica a veces hay varios inconvenientes.

Uno de las principales herramientas que se utilizan en bases de datos es la transaccionalidad que deben manejar. Supongamos debemos afectar varias tablas con una inserción, ¿qué pasa si nuestra 3º tabla que insertamos falla? Tenemos que volver atrás haciendo rollback (ver: transacciones con SQL Server). ¿Qué pasa con Linq y cómo podemos hacer una transacción desde el código c#?

Supongamos un schema LinqToSQL como el siguiente:

y supongamos que por regla de negocio, al insertar un usuario, éste DEBE ir asociado a lo menos a 1 cliente. Esta condición implica que una inserción en la tabla usuario implica a lo menos una inserción en la tabla ClientUser, si falla la inserción en ClientUser, entonces hay que hacer rollback.

Vamos al código:

public class DataRetriever
{
	/// <summary>
	/// Base de datos a la cual consultar
	/// </summary>
	LinqToUserDBDataContext _userDB;

	/// <summary>
	/// Constructor de la clase, inicializa sus componentes
	/// </summary>
	public Retriever()
	{
		this._userDB = new LinqToUserDBDataContext();
	}

	/// <summary>
	/// Guarda un usuario en la base de datos. El usuario debe tener a lo menos un cliente asociado.
	/// </summary>
	/// <param name="user">Usuario a ingresar a la base de datos</param>
	/// <param name="clientUsers">Cliente asociado</param>
	/// <returns>Retorna el usuario insertado con sus atributos.</returns>
	public User SetUser(User user, List<Client> clientUsers)
	{
		User insertedUser = new User();

		List<User> validatedUsers = (from u in this._userDB.Users
							 where u.Username == user.Username
							 select u).ToList<User>();

		if (validatedUsers.Count > 0)
		{
			throw new Exception("Ya existe un usuario con Username: " + user.Username);
		}
		else
		{
			try
			{
				System.Data.Common.DbTransaction transaction;
				this._userDB.Connection.Open();
				transaction = this._userDB.Connection.BeginTransaction();
				this._userDB.Transaction = transaction;
				User insertUser = new User
				{
					Name = user.Name
					, Email = user.Email
					, IsActive = user.IsActive
					, Password = this.EncryptMD5(user.Password)
					, Phone = user.Phone
					, Username = user.Username
				};
				this._userDB.Users.InsertOnSubmit(insertUser);
				this._userDB.SubmitChanges();

				foreach (Client c in clientUsers)
				{
					ClientUser cu = new ClientUser
					{
						UserID = insertUser.UserID
						, ClientID = c.ClientID
					};
					this._userDB.ClientUsers.InsertOnSubmit(cu);
				}
				this._userDB.SubmitChanges();

				this._userDB.Transaction.Commit();
				insertedUser = insertUser;
			}
			catch
			{
				this._userDB.Transaction.Rollback();
				throw;
			}
		}
		return insertedUser;
	}
}

Como pueden notar, los elementos característicos de una transacción están incluidos en el código c#. Si en algún punto la transacción falla, caerá al catch y se realizará el rollback.

Enjoy!

From → .NET Framework, C#, Linq

Dejar un comentario

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: