• MVC数据访问小结 ( virtual 、 volatile)


    简单写一些有关MVC公共数据处理层的使用及介绍

    一个命名空间说明了一切:

    namespace Opentide.DataAccess
    {
        /// <summary>公共数据访问处理层
        /// 
        /// </summary>
        public class DubaiCircle : DbContext
        {
            #region 变量属性
    
            //DBContext为数据库连接字符串
            private DubaiCircle()
                : base("name=DBContext")
            {
    
            }
            
            //volatile用来保持多线程数据同步
            private volatile static DubaiCircle instanceDB = null;
    
            private static readonly object lockHelper = new object();
    
            /// <summary>
            /// 数据访问公开实例对象
            /// </summary>
            public static DubaiCircle InstanceDB
            {
                get
                {
                    if (instanceDB == null)
                    {
                        lock (lockHelper)
                        {
                            if (instanceDB == null)
                                instanceDB = new DubaiCircle();
                        }
                    }
                    return instanceDB;
                }
            }
                
            //定义虚方法对实体TR_Words进行增删改查
            public virtual DbSet<TR_Words> TR_Words { get; set; }
    
            public virtual DbSet<TR_DefaultDataStore> TR_DefaultDataStore { get; set; }
            #endregion
    
    
            #region 公共方法
            //在完成对派生上下文的模型的初始化后,并在该模型已锁定并用于初始化上下文之前,将调用此方法。虽然此方法的默认实现不执行任何操作,但可在派生类中重写此方法,这样便能在锁定模型之前对其进行进一步的配置。
            //modelBuilder:定义要创建的上下文的模型的生成器。
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//移除复数表名的契约
                modelBuilder.Conventions.Remove<IncludeMetadataConvention>();//移除对MetaData表的查询验证,要不然每次都要访问EdmMetadata这个表
            }
            #endregion
        }
    }
    View Code

    别忘了添加配置webConfig文件

    <connectionStrings>
    <add name="DBContext" providerName="System.Data.SqlClient" connectionString="Data Source=.; User ID=sa;Password=123; MultipleActiveResultSets=true" />
    </connectionStrings>

    使用:

    public bool UpdateDefaultDataStore(TR_DefaultDataStore DataStore)
            {
                var list = DubaiCircle.InstanceDB.TR_DefaultDataStore.Find(DataStore.ID);
                if (list != null)
                {
                    list.UserID = DataStore.UserID;
                    list.Type = DataStore.Type;
                    list.DataName = DataStore.DataName;
                    list.DataValue = DataStore.DataValue;
    
                    DubaiCircle.InstanceDB.SaveChanges();
                    return true;
                }
                else
                {
                    return false;
                }
            }

    传统使用方式:

    private static bool InsertToJourneyPlan(DataTable dt)
            {
                string connectionString = ConfigurationManager.ConnectionStrings["DBContext"].ConnectionString;
                using (SqlConnection destinationConnection = new SqlConnection(connectionString))
                {
                    destinationConnection.Open();

             //开始存储过程
    var sqlTransaction = destinationConnection.BeginTransaction(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection, SqlBulkCopyOptions.TableLock, sqlTransaction)) { try { bulkCopy.DestinationTableName = "IR_JourneyPlan";//要插入的表的表名 bulkCopy.ColumnMappings.Add("UserID", "UserID"); bulkCopy.ColumnMappings.Add("StoreID", "StoreID"); bulkCopy.ColumnMappings.Add("Week", "Week");

    bulkCopy.BatchSize = 10000; bulkCopy.BulkCopyTimeout = 900; bulkCopy.WriteToServer(dt); sqlTransaction.Commit(); return true; } catch (Exception ex) { LogHelper.Log(ex); sqlTransaction.Rollback(); return false; } } } }

    相关使用个人理解:

    (1)virtual 

    虚方法:说白了就是给你一个自己定义的机会,如果子类方法重写父类方法,则使用时会调用子类方法。

    非虚方法:子类方法跟父类方法是两个方法,谁调用执行谁。

    容易混淆的地方在于父类用了虚方法,子类new 一个同名方法还是override同名方法。new则替代父类方法,相当于非虚方法使用。

    class A
        {
            public virtual void F() { Console.WriteLine("A.F"); }
        }
        class B : A
        {
            public override void F() { Console.WriteLine("B.F"); }  //重写A类中的虚方法
        }
        class C : B
        {
            new public virtual void F() { Console.WriteLine("C.F"); } //隐藏B类中重写过的方法,只剩下这里的虚方法会被显示,但被D重写。
        }
        class D : C
        {
            public override void F() { Console.WriteLine("D.F"); } //重写C类中的虚方法
        }    
    static void Main(string[] args)
            {
                D d = new D();
                A a = d;
                B b = d;
                C c = d;
                a.F();  //A类中的虚方法被重写为B类中的F(),所以显示结果为BF。
                b.F();  //B类中的F()方法被调用,所以显示BF
                c.F();  //B类中的重写方法被隐藏,调用C类中的虚方法,儿虚方法被D重写,故调用D类的F(),显示结果为DF
                d.F();   //寻找基类C中的虚方法,C的基类A中的虚方法不被执行,也就说明虚方法重载只能从上一辈重载
                Console.ReadKey();
            }
    View Code

    详细内容请参考:http://www.cnblogs.com/knowledgesea/archive/2012/04/17/2453753.html

    (2)volatile

    就是为了读取最新数据。

    官方解释:指示一个字段可以由多个同时执行的线程修改。

    声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值。

         volatile 修饰符通常用于由多个线程访问但不使用 lock 语句对访问进行序列化的字段。

    volatile 关键字可应用于以下类型的字段:

    • 引用类型。

    • 指针类型(在不安全的上下文中)。请注意,虽然指针本身可以是可变的,但是它指向的对象不能是可变的。换句话说,您无法声明“指向可变对象的指针”。

    • 类型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。

    • 具有以下基类型之一的枚举类型:byte、sbyte、short、ushort、int 或 uint。

    • 已知为引用类型的泛型类型参数。

    • IntPtr 和 UIntPtr

    可变关键字仅可应用于类或结构字段。不能将局部变量声明为 volatile

    (3)DBContext

    看到不错的使用,果断MARK,有机会试用

    使用Load方法将数据放入缓存

    private static void GetLocalDestinationCountWithLoad()
    {
      using (var context = new BreakAwayContext())
      {
        context.Destinations.Load();
        var count = context.Destinations.Local.Count;
        Console.WriteLine("Destinations in memory: {0}", count);
      }
    }

    本地查询(去缓存找数据)

    private static void GetLocalDestinationCount()
    {
      using (var context = new BreakAwayContext())
      {
        var count = context.Destinations.Local.Count;
        Console.WriteLine("Destinations in memory: {0}", count);
      }
    }

    参考博文:http://www.cnblogs.com/mbailing/archive/2012/07/30/2615507.html

    最后记录一下新增查询条件的心得:

    对于复杂模型,后台逻辑也很复杂,尤其是报表、图表之类的,有可能一个属性表示一个集合传到前台展示,如果要对部门新增查询操作,最好在集合末尾要返回显示数据的时候加查询。当然,如果能在基础数据中加就更好了。

  • 相关阅读:
    06.04 html
    汉企第一天
    Django之ajax
    Diango之图书管理系统编辑
    Django之模型层&ORM操作
    Django 之模板层
    Django之 路由层
    Django之ORM简单操作(一)
    迭代器、可迭代对象、迭代器对象、生成器、生成器对象、枚举对象
    装饰器
  • 原文地址:https://www.cnblogs.com/FlyBKB/p/5055845.html
Copyright © 2020-2023  润新知