.NET 常用ORM之SubSonic
一、SubSonic简单介绍
SubSonic是一个类似Rails的开源.NET项目。你可以把它看作是一把瑞士军刀,它可以用来构建Website和通过ORM方式来访问数据。Rob Conery和Eric Kemp是推动SubSonic的主要开发人员,与项目良好的发展有着密切的关系。是一个优秀的、开源的ORM映射框架。
另外官方有提供符合自身需要的代码生成器sonic.exe,但是笔者在SubSonic并未下载到类代码生成器,而是按照SubSonic的映射规则,在之前的用过的SubSonic的类上面做的修改,为下文的demo所使用,如果哪位朋友有SubSonic代码生成器连接,欢迎共享一下给大家。
二、SubSonic使用步骤
1、新增SubSonic配置文件并引入SubSonic.dll
配置文件并不多,有三处分别加入到web.config
<configSections>
<section name="SubSonicService" type="SubSonic.SubSonicSection, SubSonic" allowDefinition="MachineToApplication" restartOnExternalChanges="true" requirePermission="false"/>
</configSections>
<connectionStrings>
<add name ="SubSonicConn" connectionString="Data Source=.;Initial Catalog=Test;Integrated Security=true;uid=sa;password=XXXXXX;"/>
</connectionStrings>
<SubSonicService defaultProvider="SubSonicConn" enableTrace="false" templateDirectory="">
<providers>
<clear/>
<add name="SubSonicConn" type="SubSonic.SqlDataProvider, SubSonic"
connectionStringName="SubSonicConn" generatedNamespace="SubSonicConn" removeUnderscores="false" />
</providers>
</SubSonicService>
配置文件就这样,注意数据连接串的name值,包括后面项目中映射类文件的name值,一定要保持一致。
2、项目下新建Generated文件夹,保存SubSonic所需的类映射文件
其中Rolexxx相关为Role表的使用类,AllStructs.cs为主要的控制器文件,StoredProcedures.cs为存储过程相关的类。具体类代码如下:
using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
using SubSonic;
using SubSonic.Utilities;
// <auto-generated />
namespace ORMSubSonic.Generated
{
#region Tables Struct
public partial struct Tables
{ public static readonly string Boy = @"boy"; }
#endregion
#region Schemas
public partial class Schemas { public static TableSchema.Table Boy
{
get { return DataService.GetSchema("boy", "SubSonicConn"); }
} }
#endregion
#region View Struct
public partial struct Views
{ }
#endregion #region Query Factories
public static partial class DB
{
public static DataProvider _provider = DataService.Providers["SubSonicConn"];
static ISubSonicRepository _repository;
public static ISubSonicRepository Repository
{
get
{
if (_repository == null)
return new SubSonicRepository(_provider);
return _repository;
}
set { _repository = value; }
}
public static Select SelectAllColumnsFrom<T>() where T : RecordBase<T>, new()
{
return Repository.SelectAllColumnsFrom<T>();
}
public static Select Select()
{
return Repository.Select();
} public static Select Select(params string[] columns)
{
return Repository.Select(columns);
} public static Select Select(params Aggregate[] aggregates)
{
return Repository.Select(aggregates);
} public static Update Update<T>() where T : RecordBase<T>, new()
{
return Repository.Update<T>();
} public static Insert Insert()
{
return Repository.Insert();
} public static Delete Delete()
{
return Repository.Delete();
} public static InlineQuery Query()
{
return Repository.Query();
} }
#endregion }
#region Databases
public partial struct Databases
{ public static readonly string SubSonicConn = @"SubSonicConn"; }
#endregion
using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
using SubSonic;
using SubSonic.Utilities;
// <auto-generated />
namespace ORMSubSonic.Generated
{
/// <summary>
/// Strongly-typed collection for the Role class.
/// </summary>
[Serializable]
public partial class RoleCollection : ActiveList<Role, RoleCollection>
{
public RoleCollection() { } /// <summary>
/// Filters an existing collection based on the set criteria. This is an in-memory filter
/// Thanks to developingchris for this!
/// </summary>
/// <returns>RoleCollection</returns>
public RoleCollection Filter()
{
for (int i = this.Count - ; i > -; i--)
{
Role o = this[i];
foreach (SubSonic.Where w in this.wheres)
{
bool remove = false;
System.Reflection.PropertyInfo pi = o.GetType().GetProperty(w.ColumnName);
if (pi.CanRead)
{
object val = pi.GetValue(o, null);
switch (w.Comparison)
{
case SubSonic.Comparison.Equals:
if (!val.Equals(w.ParameterValue))
{
remove = true;
}
break;
}
}
if (remove)
{
this.Remove(o);
break;
}
}
}
return this;
} }
/// <summary>
/// This is an ActiveRecord class which wraps the Role table.
/// </summary>
[Serializable]
public partial class Role : ActiveRecord<Role>, IActiveRecord
{
#region .ctors and Default Settings public Role()
{
SetSQLProps();
InitSetDefaults();
MarkNew();
} private void InitSetDefaults() { SetDefaults(); } public Role(bool useDatabaseDefaults)
{
SetSQLProps();
if (useDatabaseDefaults)
ForceDefaults();
MarkNew();
} public Role(object keyID)
{
SetSQLProps();
InitSetDefaults();
LoadByKey(keyID);
} public Role(string columnName, object columnValue)
{
SetSQLProps();
InitSetDefaults();
LoadByParam(columnName, columnValue);
} protected static void SetSQLProps() { GetTableSchema(); } #endregion #region Schema and Query Accessor
public static Query CreateQuery() { return new Query(Schema); }
public static TableSchema.Table Schema
{
get
{
if (BaseSchema == null)
SetSQLProps();
return BaseSchema;
}
} private static void GetTableSchema()
{
if (!IsSchemaInitialized)
{
//Schema declaration
TableSchema.Table schema = new TableSchema.Table("Role", TableType.Table, DataService.GetInstance("SubSonicConn"));
schema.Columns = new TableSchema.TableColumnCollection();
schema.SchemaName = @"dbo";
//columns TableSchema.TableColumn colvarId = new TableSchema.TableColumn(schema);
colvarId.ColumnName = "id";
colvarId.DataType = DbType.Int32;
colvarId.MaxLength = ;
colvarId.AutoIncrement = true;
colvarId.IsNullable = false;
colvarId.IsPrimaryKey = true;
colvarId.IsForeignKey = false;
colvarId.IsReadOnly = false;
colvarId.DefaultSetting = @"";
colvarId.ForeignKeyTableName = "";
schema.Columns.Add(colvarId); TableSchema.TableColumn colvarUid = new TableSchema.TableColumn(schema);
colvarUid.ColumnName = "uid";
colvarUid.DataType = DbType.Int32;
colvarUid.MaxLength = ;
colvarUid.AutoIncrement = false;
colvarUid.IsNullable = true;
colvarUid.IsPrimaryKey = false;
colvarUid.IsForeignKey = false;
colvarUid.IsReadOnly = false;
colvarUid.DefaultSetting = @"";
colvarUid.ForeignKeyTableName = "";
schema.Columns.Add(colvarUid); TableSchema.TableColumn colvarRoleName = new TableSchema.TableColumn(schema);
colvarRoleName.ColumnName = "rolename";
colvarRoleName.DataType = DbType.AnsiString;
colvarRoleName.MaxLength = ;
colvarRoleName.AutoIncrement = false;
colvarRoleName.IsNullable = true;
colvarRoleName.IsPrimaryKey = false;
colvarRoleName.IsForeignKey = false;
colvarRoleName.IsReadOnly = false;
colvarRoleName.DefaultSetting = @"";
colvarRoleName.ForeignKeyTableName = "";
schema.Columns.Add(colvarRoleName); TableSchema.TableColumn colvarRemark = new TableSchema.TableColumn(schema);
colvarRemark.ColumnName = "remark";
colvarRemark.DataType = DbType.AnsiString;
colvarRemark.MaxLength = ;
colvarRemark.AutoIncrement = false;
colvarRemark.IsNullable = true;
colvarRemark.IsPrimaryKey = false;
colvarRemark.IsForeignKey = false;
colvarRemark.IsReadOnly = false;
colvarRemark.DefaultSetting = @"";
colvarRemark.ForeignKeyTableName = "";
schema.Columns.Add(colvarRemark); BaseSchema = schema;
//add this schema to the provider
//so we can query it later
DataService.Providers["SubSonicConn"].AddSchema("Role", schema);
}
}
#endregion #region Props [XmlAttribute("Id")]
[Bindable(true)]
public int Id
{
get { return GetColumnValue<int>(Columns.Id); }
set { SetColumnValue(Columns.Id, value); }
} [XmlAttribute("Uid")]
[Bindable(true)]
public int? Uid
{
get { return GetColumnValue<int?>(Columns.Uid); }
set { SetColumnValue(Columns.Uid, value); }
} [XmlAttribute("RoleName")]
[Bindable(true)]
public string RoleName
{
get { return GetColumnValue<string>(Columns.RoleName); }
set { SetColumnValue(Columns.RoleName, value); }
} [XmlAttribute("Remark")]
[Bindable(true)]
public string Remark
{
get { return GetColumnValue<string>(Columns.Remark); }
set { SetColumnValue(Columns.Remark, value); }
} #endregion //no foreign key tables defined (0) //no ManyToMany tables defined (0) #region ObjectDataSource support /// <summary>
/// Inserts a record, can be used with the Object Data Source
/// </summary>
public static void Insert(int? varUid, string varRoleName, string varRemark)
{
Role item = new Role(); item.Uid = varUid; item.RoleName = varRoleName; item.Remark = varRemark; if (System.Web.HttpContext.Current != null)
item.Save(System.Web.HttpContext.Current.User.Identity.Name);
else
item.Save(System.Threading.Thread.CurrentPrincipal.Identity.Name);
} /// <summary>
/// Updates a record, can be used with the Object Data Source
/// </summary>
public static void Update(int varId, int? varUid, string varRoleName, string varRemark)
{
Role item = new Role(); item.Id = varId; item.Uid = varUid; item.RoleName = varRoleName; item.Remark = varRemark; item.IsNew = false;
if (System.Web.HttpContext.Current != null)
item.Save(System.Web.HttpContext.Current.User.Identity.Name);
else
item.Save(System.Threading.Thread.CurrentPrincipal.Identity.Name);
}
#endregion #region Typed Columns public static TableSchema.TableColumn IdColumn
{
get { return Schema.Columns[]; }
} public static TableSchema.TableColumn UidColumn
{
get { return Schema.Columns[]; }
} public static TableSchema.TableColumn RoleNameColumn
{
get { return Schema.Columns[]; }
} public static TableSchema.TableColumn RemarkColumn
{
get { return Schema.Columns[]; }
} #endregion
#region Columns Struct
public struct Columns
{
public static string Id = @"id";
public static string Uid = @"uid";
public static string RoleName = @"rolename";
public static string Remark = @"remark"; }
#endregion #region Update PK Collections #endregion #region Deep Save #endregion
}
}
using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
using SubSonic;
using SubSonic.Utilities;
// <auto-generated />
namespace ORMSubSonic.Generated
{
/// <summary>
/// Controller class for Role
/// </summary>
[System.ComponentModel.DataObject]
public partial class RoleController
{
// Preload our schema..
Role thisSchemaLoad = new Role();
private string userName = String.Empty;
protected string UserName
{
get
{
if (userName.Length == )
{
if (System.Web.HttpContext.Current != null)
{
userName=System.Web.HttpContext.Current.User.Identity.Name;
}
else
{
userName=System.Threading.Thread.CurrentPrincipal.Identity.Name;
}
}
return userName;
}
}
[DataObjectMethod(DataObjectMethodType.Select, true)]
public RoleCollection FetchAll()
{
RoleCollection coll = new RoleCollection();
Query qry = new Query(Role.Schema);
coll.LoadAndCloseReader(qry.ExecuteReader());
return coll;
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public RoleCollection FetchByID(object Id)
{
RoleCollection coll = new RoleCollection().Where("id", Id).Load();
return coll;
} [DataObjectMethod(DataObjectMethodType.Select, false)]
public RoleCollection FetchByQuery(Query qry)
{
RoleCollection coll = new RoleCollection();
coll.LoadAndCloseReader(qry.ExecuteReader());
return coll;
}
[DataObjectMethod(DataObjectMethodType.Delete, true)]
public bool Delete(object Id)
{
return (Role.Delete(Id) == );
}
[DataObjectMethod(DataObjectMethodType.Delete, false)]
public bool Destroy(object Id)
{
return (Role.Destroy(Id) == );
} /// <summary>
/// Inserts a record, can be used with the Object Data Source
/// </summary>
[DataObjectMethod(DataObjectMethodType.Insert, true)]
public void Insert(int? Uid,string RoleName,string Remark)
{
Role item = new Role(); item.Uid = Uid; item.RoleName = RoleName; item.Remark = Remark; item.Save(UserName);
} /// <summary>
/// Updates a record, can be used with the Object Data Source
/// </summary>
[DataObjectMethod(DataObjectMethodType.Update, true)]
public void Update(int Id, int? Uid, string RoleName, string Remark)
{
Role item = new Role();
item.MarkOld();
item.IsLoaded = true; item.Id = Id; item.Uid = Uid; item.RoleName = RoleName; item.Remark = Remark; item.Save(UserName);
}
}
}
using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
using SubSonic;
using SubSonic.Utilities;
// <auto-generated />
namespace ORMSubSonic.Generated
{
public partial class SPs{ } }
3、实际使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SubSonic;
using ORMSubSonic.Generated;
using System.Data; namespace ORMSubSonic.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
//1.增加
Generated.Role modRole = new Generated.Role();
modRole.Uid = ;
modRole.RoleName = "Subsonic操作手";
modRole.Remark = "Subsonic操作手备注信息";
modRole.Save(); //2.删除
int result = DB.Delete().From(Role.Schema)
.Where(Role.Columns.Id).IsEqualTo("").Execute(); //3.修改
int result2 = new Update(Role.Schema)
.Set(Role.Columns.RoleName).EqualTo("Subsonic操作手(修改)")
.Where(Role.Columns.Id).IsEqualTo("").Execute(); ////4.查询
//DataTable dt= DB.Select().From(Role.Schema).ExecuteDataSet().Tables[0];
DataTable dt = new Select().From(Role.Schema).ExecuteDataSet().Tables[]; ////5.分页查询
DataTable dt2 = new Select().From(Role.Schema)
.Paged(,,Role.Columns.Id)
.OrderAsc(Role.Columns.Id)
.ExecuteDataSet().Tables[]; return View();
}
}
}
4、SubSonic语法
SubSonic语法有点特别,用过SubSonic的人都比较喜欢SubSonic的语法,因人而异。在这里笔者就简单的介绍下SubSonic常用的方法和关键字
4.1、常用方法
Ø ExecuteReader(); 返回DataReader
Ø ExecuteScalar(); 返回对象
Ø ExecuteScalar<string>(); 返回泛型对象
Ø ExecuteSingle<Product>(); 返回表实体对象
Ø ExecuteTypedList<Product>(); 返回泛型表实休数据集
Ø ExecuteDataSet(); 返回DataSet
Ø ExecuteJoinedDataSet<强数型数据集>(); 返回关联查询 DataSet
Ø Execute(); 返回执行后数据更新数目
4.2、常用关键字
Ø IsEqualTo(obj) // 等于 value
Ø IsBetweenAnd(obj1, obj2) // [字段1] BETWEEN 值1 AND 值2
Ø StartsWith // LIEK '1%‘
Ø EndsWith // LIEK '%1‘
Ø IsGreaterThan // [字段1] > 值1
Ø IsGreaterThanOrEqualToIsGreaterThan // [字段1] >= 值1
Ø IsLessThan // [字段1] < 值1
Ø IsLessThanOrEqualToIsLessThan // [字段1] <= 值1
Ø WhereExpression / AndExpression // Expression 表示括号
eg:
.Where("1").IsGreaterThan(1)
.And("2").IsGreaterThanOrEqualTo(2)
.AndExpression("3").IsLessThan(3)
.AndExpression("4").IsLessThanOrEqualTo(4).And("5").StartsWith("5")
.AndExpression("6").EndsWith("6")
.ExecuteSingle<Product>();
实际在SQL中执行语句则是:
where 1>1 and 2>=2 and (3<3) and (4<=4 and 5 like '5%') and (6 like '%6')
4.3、多表查询
eg:查询Product表中产品关联的种类名称,并且CategoryID大于4的记录
DataSet ds = new Select(Product.ProductNameColumn, Category.CategoryIDColumn,Category.CategoryNameColumn)
.From<Product>()
.InnerJoin(Category.CategoryIDColumn, Product.CategoryIDColumn)
.Where(Category.CategoryIDColumn) .IsGreaterThan(4)
.ExecuteDataSet().Table[0];
Select中的列则是在在DataGridView显示的列ProductName,CategoryID,CategoryName
4.4、分页查询
在标题三代码使用中已经使用到,在这里就不举例说明,具体语法就是:
SqlQuery Paged(int currentPage, int pageSize);
SqlQuery Paged(int currentPage, int pageSize, string idColumn);
.NET 常用ORM之SubSonic的更多相关文章
- ORM概述及常用ORM框架
一.ORM ORM(Object-relational mapping),即对象关系映射,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.也就是说,ORM是通过使用描述对象和数据库之间映 ...
- .NET 常用ORM之iBatis
ibatis 一词来源于“internet”和“abatis”的组合,是一个由Clinton Begin在2001年发起的开放源代码项目,到后面发展的版本叫MyBatis但都是指的同一个东西.最初侧重 ...
- .NET 常用ORM之Gentle.Net
.Net常用的就是微软的EF框架和Nhibernate,这两个框架用的都比较多就不做详细介绍了,今天我们来看看Gentle.Net,Gentle.Net是一个开源的优秀O/R Mapping的对象持久 ...
- .Net 常用ORM框架对比:EF Core、FreeSql、SqlSuger
前言: 最近由于工作需要,需要选用一种ORM框架,也因此对EF Core.FreeSql.SqlSuger作简单对比.个人认为各有有优势,存在即合理,不然早就被淘汰了是吧,所以如何选择因人而议.因项目 ...
- .NET 常用ORM之NHibernate
NHibernate做.Net应该都不陌生,今天我们就算是温故下这个技术,概念性的东西就不说了,这次主要说本人在实际使用的遇到的问题,比较费解现在就当是记录下,避免以后再犯.本次主要使用的情况是1对N ...
- .NET 常用ORM之Nbear
NBear是一个基于.Net 2.0.C#2.0开放全部源代码的的软件开发框架类库.NBear的设计目标是尽最大努力减少开发人员的工作量,最大程度提升开发效率,同时兼顾性能及可伸缩性. 一.新建项目并 ...
- yii 常用orm
yii2 orwhere andwhere的复杂写法:https://www.codercto.com/a/6513.html $files = XXXX::find() ->andWhere( ...
- django ORM
http://www.cnblogs.com/alex3714/articles/5512568.html 常用ORM操作 一.示例Models from django.db import model ...
- 轻量级ORM框架 QX_Frame.Bantina(二、框架使用方式介绍)
轻量级ORM框架QX_Frame.Bantina系列讲解(开源) 一.框架简介 http://www.cnblogs.com/qixiaoyizhan/p/7417467.html 二.框架使用方式介 ...
随机推荐
- RN animated缩放动画
效果图: 代码: import React, {Component} from 'react'; import { AppRegistry, StyleSheet, Text, Animated, T ...
- 20190228 搭建Hadoop基础环境
下载VMware 12 版本以上 下载CentOS 7以上版本 安装虚拟机,安装系统时,注意设置root 账号和密码 虚拟机配置网络,命令ip addr 查看IP 地址,(配置网络网上有很多办法,百度 ...
- vue中filter的用法
test() { var arr1 = ["A", "B", "C","C","A"]; var r ...
- 虚函数后面的const=0
const 和 =0要分开理解. 成员函数后面用 const 修饰,const表示this是一个指向常量的指针,即对象成为一个常量,即它的成员不能够变化.(默认情况下,this的类型是指向类类型非常量 ...
- 将 context node 中的内容 分配给 desing layer
1 将 context node 中的内容 分配给 desing layer 选中context node 右键>assignment to design layer.
- [django]form的content-type(mime)
form默认的content-type是 'application/x-www-form-urlencoded' 可以修改为多文档: enctype即为mime类型 <form action=& ...
- left join不同写法导致数据差异
select m.*, p.specification, p.sales_price, p.promotion_price from product_detail p left join PRODUC ...
- 新发现:排序算法时间复杂度只有O(3n),命名为"wgw"排序法
思路:首先在待排序数组i[]中找出最大的值,以(最大值+1)的大小创建一个空数组kk[],然后遍历待排序数组i[]中的值n,其值n对应数组kk[]中的第n个元素加1.最后再把数组kk[]排好序的值赋回 ...
- JS通过类名判断是否都必填
//判断class='required' 是否都必填 function required() { var flag = true; $(".required").each(func ...
- python beautiful soup库的超详细用法
原文地址https://blog.csdn.net/love666666shen/article/details/77512353 参考文章https://cuiqingcai.com/1319.ht ...