+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / OpenAccess data layer

OpenAccess data layer

2 posts, 0 answered
  1. Nathan
    Nathan avatar
    5 posts
    Registered:
    30 Sep 2008
    30 Jul 2010
    Link to this post
    I was wondering what the recommended way is to set up a data layer for use with OpenAccess and Sitefinity 3.7?
    I have set up my module and data layer in separate projects and am using the provider model approach as recommended.  I can add new objects to the database without any problem and retrieve those objects, however my module throws an Active transaction required for write operation exception whenever I try to update any of my persistent classes

    I have a feeling it has something to do with scope management but I really cannot see where I am going wrong when obtaining the scope and using it for transactions. 

    All the examples I have seen seem to use Nolics which I have read as being phased out in Sitefinity 4.0.

    The error always happens when calling the following piece of code from my module.

    01.void Grid_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
    02.{
    03.          
    04.         Products = Manager.Provider.GetAllProducts();
    05.         foreach (var product in Products)
    06.         {
    07.             product.ProcessingID = Guid.NewGuid().ToString(); // Error happens here
    08.         }
    09.         Grid.DataSource = Products;
    10.}


    Below is my DefaultProvider class from my data layer with the CRUD operations.
    001.using System;
    002.using System.Collections;
    003.using System.Collections.Generic;
    004.using System.Linq;
    005.using System.Text;
    006. 
    007.namespace ARIS.Importer.Data
    008.{
    009. 
    010.    using ARIS.Importer;
    011.    using ARIS.Importer.Data.Resources;
    012.    using System.Reflection;
    013.    using Telerik.OpenAccess;
    014.    using Telerik.OpenAccess.Query;
    015.    using Telerik;
    016.    using Telerik.DataAccess;
    017.    using Telerik.Security;
    018.    using ARIS.Importer.Configuration;
    019.    using System.IO;
    020. 
    021.    public class DefaultProvider : ImporterProvider
    022.    {
    023. 
    024.        private IObjectScope scope;
    025. 
    026.        /// <summary>
    027.        /// Returns the database scope
    028.        /// </summary>
    029.        public IObjectScope Scope
    030.        {
    031.            get
    032.            {
    033.                    if(scope == null)
    034.                    scope = ObjectScopeProvider1.GetNewObjectScope();
    035.    
    036.                return scope;
    037.            }
    038.        }
    039. 
    040.        public DefaultProvider()
    041.        {
    042.             
    043.        }
    044. 
    045.        #region Overrides of ImporterProvider
    046. 
    047.        /// <summary>
    048.        /// Refresh the cache with new information
    049.        /// </summary>
    050.        public override void RefreshCache()
    051.        {
    052.            var cacheManager = new CacheManager();
    053.            cacheManager.Provider.RefreshCache();
    054. 
    055.        }
    056. 
    057.        /// <summary>
    058.        /// Gets a list of all products in the database
    059.        /// </summary>
    060.        /// <returns></returns>
    061.        public override IList<Product> GetAllProducts()
    062.        {
    063.            var products = Scope.Extent<Product>();
    064.            return products.ToList();
    065.             
    066.        }
    067. 
    068.        /// <summary>
    069.        /// Get a single product
    070.        /// </summary>
    071.        /// <param name="productId">Unique identifier</param>
    072.        /// <returns></returns>
    073.        public override Product GetProduct(int productId)
    074.        {
    075.            var existingProduct =
    076.           (from p in Scope.Extent<ARIS.Product>().Where
    077.                (p => p.ProductId == productId)
    078.            select p).Single();
    079.            return existingProduct;
    080. 
    081.        }
    082. 
    083.        /// <summary>
    084.        /// Update a single product
    085.        /// </summary>
    086.        /// <param name="data"></param>
    087.        public override void UpdateProduct(Product data)
    088.        {
    089.            Scope.Transaction.Begin();
    090.            if(data == null)
    091.                return;
    092.            var existingProduct =
    093.           (from p in Scope.Extent<ARIS.Product>().Where
    094.                (p => p.ProductId == data.ProductId )
    095.            select p).Single();
    096.            existingProduct = data;
    097.            Scope.Transaction.Commit();
    098.            Scope.Dispose();
    099.             RefreshCache();
    100. 
    101.             
    102.        }
    103. 
    104. 
    105. 
    106.        /// <summary>
    107.        /// Add a new product
    108.        /// </summary>
    109.        /// <param name="data"></param>
    110.        public override void AddProduct(Product data)
    111.        {
    112.            Scope.Transaction.Begin();
    113.            Scope.Add(data);
    114.            Scope.Transaction.Commit();
    115.            Scope.Dispose();
    116.            RefreshCache();
    117.        }
    118. 
    119.        /// <summary>
    120.        /// Add multiple products
    121.        /// </summary>
    122.        /// <param name="data"></param>
    123.        public override void AddProduct(IList<Product> data)
    124.        {
    125.            Scope.Transaction.Begin();
    126.            Scope.Add(data);
    127.            Scope.Transaction.Commit();
    128.            Scope.Dispose();
    129.            RefreshCache();
    130.        }
    131. 
    132.        /// <summary>
    133.        /// Gets a listing directory files, cross checks
    134.        /// against products in the database.
    135.        /// </summary>
    136.        /// <returns></returns>
    137.        public override IList<Product> GetAllImportFiles()
    138.        {
    139.            var directoryInfo = new DirectoryInfo(ImportDirectory);
    140.            var files = directoryInfo.GetFiles(ImportFilePattern);
    141. 
    142.            var listing = new List<Product>();
    143. 
    144.            foreach (var fileInfo in files)
    145.            {
    146.                // cross check against the database for matches
    147.                var product = (from p in Scope.Extent<ARIS.Product>()
    148.                               where p.ImportFileName.ToLower() == fileInfo.Name.ToLower()
    149.                               select p).Single();
    150.                if(product==null)
    151.                    listing.Add(Product.GenerateProductFromFileInfo(fileInfo));
    152.                else
    153.                    listing.Add(product);
    154.            }
    155. 
    156.            return listing;
    157.        }
    158. 
    159.        /// <summary>
    160.        /// Gets a listing of directory files, filtered by
    161.        /// status and then crosschecks against the database before returning.
    162.        /// </summary>
    163.        /// <param name="status"></param>
    164.        /// <returns></returns>
    165.        public override IList<Product> GetAllImportFiles(ImportStatus status)
    166.        {
    167.             
    168.            var allProducts = GetAllImportFiles();
    169.            var listing = new List<Product>();
    170. 
    171.            foreach (var product in allProducts)
    172.            {
    173.                if(product.Status == status)
    174.                    listing.Add(product);
    175.            }
    176. 
    177.            return listing;
    178.        }
    179. 
    180.        #endregion
    181.    }
    182.}

    Apologies for the long winded code block but I thought it best to include all the DefaultProvider code just in case there is something obvious I am doing wrong somewhere in the class.

    Any advice would be appreciated.
    :)
  2. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    03 Aug 2010
    Link to this post
    Hello Nathan,

    Thank you for using our services.

    All operations that make changes to the database are encapsulated within a transaction. This ensures that all changes are committed at once to the database. It also provides the ability to rollback the changes if something bad happens, so the database will not be polluted. Transactions are managed by the ObjectScope.Transaction property and its Begin, Commit and Rollback methods. Note that only one transaction can be active at the same time for each object scope instance. I believe you will find this Knowledge base article useful.

    Kind regards,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
2 posts, 0 answered