This project is read-only.

Documentation

This document describes the basic concepts and framework architecture of the project. It explains the main objects, their purpose and functionalities. You can download the latest framework documentation from here.

Getting Started

  1. Setup all programs and frameworks that are required for use or developing.
  2. Download the latest version of the framework from here.
  3. Reference Snowflake.Gateway, Snowflake.Entities and Snowflake.Common assembies in your project.
  4. Create LINQ TO SQL Enitity objects that represents each table from your database. Derive each of the object from EntityObject class and implement the abstract methods. We recommend to separate entity object maps in standalone assembly.

Framework Overview

There are three main classes, which are the core of this data access layer:
  • EntityObject - this class is base class for each entity class that represents table from data base. The entity class has the same look as standard LINQ TO SQL classes, but inherits EntityObject class and invokes internally some of its methods. In the toturial section of this document is explained how to use it.
[Serializable]
public abstract class EntityObject
{
    // Fields
    private IEntityList _EntityList;
    private IndexedDictionary<string, object> _ExtendedProperties;
    private EntityObject _OriginalObject;
    private EntityObjectState _State;
    private EventHandler<PropertyChangedEventArgs> PropertyChanged;
    private EventHandler<PropertyChangingEventArgs> PropertyChanging;

    // Events
    public event EventHandler<PropertyChangedEventArgs> PropertyChanged;
    public event EventHandler<PropertyChangingEventArgs> PropertyChanging;

    // Methods
    public EntityObject();
    public void AcceptChanges();
    protected abstract EntityObject CreateEntityObject();
    public void Delete();
    protected virtual bool IsValidaPropertyValue<TValue>(string property, TValue value);
    public void RejectChanges();
    protected internal abstract void RestoreOriginalData(EntityObject originalObject);
    public void SetAdded();
    public void SetModified();
    protected void SetValue<TValue>(string property, TValue newValue, ref TValue oldValue);
    internal void StoreOriginalObjectDataState();

    // Properties
    internal IEntityList EntityList { get; set; }
    internal IndexedDictionary<string, object> ExtendedProperties { get; set; }
    public object this[string property] { get; set; }
    internal EntityObject OriginalObject { get; set; }
    public EntityObjectState State { get; internal set; }
}
  • EntityList<TEntity> - It's enumerable collection of type TEntity (EntityObjects). It follows the same ideology as DataTable in ADO.NET. It is tracking all changes made in its entities. In the toturial section of this document is explained how to use it.
[Serializable]
public class EntityList<TEntity> : IEntityList, IEnumerable<TEntity>, IEnumerable where TEntity: EntityObject
{
    // Fields
    private IList<TEntity> _List;

    // Methods
    public EntityList();
    internal EntityList(IList<TEntity> list);
    public void AcceptChanges();
    public void Delete(TEntity entity);
    public TEntity[] GetChanges(EntityObjectState state);
    public IEnumerator<TEntity> GetEnumerator();
    public void Insert(TEntity entity);
    public void RejectChanges();
    void IEntityList.AcceptChanges(EntityObject entityObject);
    void IEntityList.Delete(EntityObject entity);
    void IEntityList.RejectChanges(EntityObject entityObject);
    public void Sort<TKey>(Func<TEntity, TKey> keySelector);
    public void Sort<TKey>(Func<TEntity, TKey> keySelector, bool descending);
    IEnumerator IEnumerable.GetEnumerator();

    // Properties
    public int Count { get; }
    public TEntity this[int index] { get; }
}
  • EntityGateway - This class is the gate to the database. It's responsible for loading, inserting, updating or deleting records in the database. It translates the records from the database to EntityObjects encapsulated by EntityList and vice versa - from EntityObjects does updates/inserts/deletes depending on their state. In the toturial section of this document is explained how to use it.
public sealed class EntityGateway : IDisposable
{
    // Fields
    private bool _AcceptChangesDuringSave;
    private IDbConnection _DbConnection;
    private IDbTransaction _DbTransaction;
    private int _QueryTimeout;

    // Methods
    public EntityGateway(IDbConnection dbConnection);
    public void BeginTransaction();
    public void BeginTransaction(IsolationLevel isolationLevel);
    public void CommitTransaction();
    private DataContext CreateDataContext(bool objectTrackingEnabled);
    public void Dispose();
    public EntityList<TEntity> ExecuteQuery<TEntity>(IQueryable<TEntity> query) where TEntity: EntityObject;
    public Table<TEntity> GetTable<TEntity>() where TEntity: EntityObject;
    public EntityList<TEntity> Load<TEntity>(Expression<Func<TEntity, bool>> whereExpression) where TEntity: EntityObject;
    public EntityList<TEntity> Load<TEntity, TKey>(Expression<Func<TEntity, bool>> whereExpression, 
                                        Expression<Func<TEntity, TKey>> orderBy) where TEntity: EntityObject;
    public EntityList<TEntity> LoadAll<TEntity>() where TEntity: EntityObject;
    public TEntity LoadByPrimaryKey<TEntity>(object pkKey, params object[] pkKeys) where TEntity: EntityObject;
    public void RollbackTransaction();
    public void Save<TEntity>(EntityList<TEntity> entities) where TEntity: EntityObject;
    public void Save<TEntity>(EntityList<TEntity> entities, ConflictMode conflictMode) where TEntity: EntityObject;

    // Properties
    public bool AcceptChangesDuringSave { get; set; }
    public int QueryTimeout { get; set; }
}

Tutorials

  • How to represent table from the database as Snowflake Entity Object?
Table 'Customer' has the following schema:

Customers_Table.jpg

Its representation in Snowflake Framework is:

[Table(Name = "dbo.Customers")]
public sealed class Customer : EntityObject
{
    private string _CustomerID;
    private string _CompanyName;
    private string _ContactName;
    private string _ContactTitle;
    private string _Address;
    private string _City;
    private string _Region;
    private string _PostalCode;
    private string _Country;
    private string _Phone;
    private string _Fax;

    public Customer()
    {
    }

    [Column(Storage = "_CustomerID", DbType = "NChar(5) NOT NULL", CanBeNull = false, IsPrimaryKey = true)]
    public string CustomerID
    {
        get
        {
            return this._CustomerID;
        }
        set
        {
            SetValue<string>("CustomerID", value, ref this._CustomerID);
        }
    }

    [Column(Storage = "_CompanyName", DbType = "NVarChar(40) NOT NULL", CanBeNull = false)]
    public string CompanyName
    {
        get
        {
            return this._CompanyName;
        }
        set
        {
            SetValue<string>("CompanyName", value, ref this._CompanyName);
        }
    }

    [Column(Storage = "_ContactName", DbType = "NVarChar(30)")]
    public string ContactName
    {
        get
        {
            return this._ContactName;
        }
        set
        {
            SetValue<string>("ContactName", value, ref this._ContactName);
        }
    }

    [Column(Storage = "_ContactTitle", DbType = "NVarChar(30)")]
    public string ContactTitle
    {
        get
        {
            return this._ContactTitle;
        }
        set
        {
            SetValue<string>("ContactTitle", value, ref this._ContactTitle);
        }
    }

    [Column(Storage = "_Address", DbType = "NVarChar(60)")]
    public string Address
    {
        get
        {
            return this._Address;
        }
        set
        {
            SetValue<string>("Address", value, ref this._Address);
        }
    }

    [Column(Storage = "_City", DbType = "NVarChar(15)")]
    public string City
    {
        get
        {
            return this._City;
        }
        set
        {
            SetValue<string>("City", value, ref this._City);
        }
    }

    [Column(Storage = "_Region", DbType = "NVarChar(15)")]
    public string Region
    {
        get
        {
            return this._Region;
        }
        set
        {
            SetValue<string>("Region", value, ref this._Region);
        }
    }

    [Column(Storage = "_PostalCode", DbType = "NVarChar(10)")]
    public string PostalCode
    {
        get
        {
            return this._PostalCode;
        }
        set
        {
            SetValue<string>("PostalCode", value, ref this._PostalCode);
        }
    }

    [Column(Storage = "_Country", DbType = "NVarChar(15)")]
    public string Country
    {
        get
        {
            return this._Country;
        }
        set
        {
            SetValue<string>("Country", value, ref this._Country);
        }
    }

    [Column(Storage = "_Phone", DbType = "NVarChar(24)")]
    public string Phone
    {
        get
        {
            return this._Phone;
        }
        set
        {
            SetValue<string>("Phone", value, ref this._Phone);
        }
    }

    [Column(Storage = "_Fax", DbType = "NVarChar(24)")]
    public string Fax
    {
        get
        {
            return this._Fax;
        }
        set
        {
            SetValue<string>("Fax", value, ref this._Fax);
        }
    }

    protected override void RestoreOriginalData(EntityObject originalObject)
    {
        Customer customerOriginal = originalObject as Customer;

        this._Address = customerOriginal._Address;
        this._City = customerOriginal._City;
        this._CompanyName = customerOriginal._CompanyName;
        this._ContactName = customerOriginal._ContactName;
        this._ContactTitle = customerOriginal._ContactTitle;
        this._Country = customerOriginal._Country;
        this._CustomerID = customerOriginal._CustomerID;
        this._Fax = customerOriginal._Fax;
        this._Phone = customerOriginal._Phone;
        this._PostalCode = customerOriginal._PostalCode;
        this._Region = customerOriginal._Region;
    }

    protected override EntityObject CreateEntityObject()
    {
        return new Customer();
    }
}

To retrieve entity objects from the data base or submit entity objects you need instance of EntityGateway.

IDbConnection dbConnection = new SqlConnection(CONNECTION_STRING);
EntityGateway entityGateway = new EntityGateway(dbConnection);
  • How to load Snowflake Entity Objects from the database?
There are several ways to load entity objects depending on your needs.
1. Load All Records in specified table as EntityList
EntityList<Customer> customers = entityGateway.LoadAll<Customer>();

2. Load all records that accept specified conditions.
EntityList<Customer> customers = entityGateway.Load<Customer>(p => p.City == "Sofia");

3. Load entity object by primary key
Customer customer = entityGateway.LoadByPrimaryKey<Customer>("Snowflake");

4. Load entity objects as EntityList using LINQ TO SQL Queries
Table<Customer> table = entityGateway.GetTable<Customer>();
var query = from item in table where item.City == "London" select item;
EntityList<Customer> customers = entityGateway.ExecuteQuery<Customer>(query);
  • How to insert/update/delete Snowflake Entity Object in the database?
// Load all records - just for demonstration
EntityList<Customer> customers = entityGateway.LoadAll<Customer>();

// Change its state to deleted
customers[0].Delete();
            
// Change its state to modified
customers[1].City = "Athens";

// Create new entity object in detached state
Customer newCustomer = new Customer();
newCustomer.Address = "Unknown";
newCustomer.City = "New York";
newCustomer.CompanyName = "Snowflake";
newCustomer.ContactName = "Codeplex";
newCustomer.ContactTitle = "Mr.";
newCustomer.Country = "USA";
newCustomer.CustomerID = "SNFL";
newCustomer.Fax = "88*";
newCustomer.Phone = "112";
newCustomer.PostalCode = "SE10";
newCustomer.Region = "North America";

// Add detached object in collection and change its state to Added
customers.Insert(newCustomer);

// Do Insert/Update/Delete depeding on the state of the objects in collection
entityGateway.Save<Customer>(customers);

Last edited Oct 22, 2009 at 10:55 AM by eldorado, version 53

Comments

No comments yet.