讲讲Linq to SQL映射(基础篇)
??????? 這篇主要講Linq to? SQL基于屬性的映射。即映射數據庫,映射表,映射列,映射關系,映射存儲過程,
映射函數。然而創建這種映射有三種方法,他們分別是ORD工具,SQLMetal命令行工具,以及編寫手工代碼
創建。
??????? 咱們首先了解下手工創建屬性映射的方法,這樣你就能看懂基于工具產生的代碼了。他們的區別也就是
使用工具效率會更高些,但前提需要先設計好數據庫,這樣就可以直接通過數據庫的結構輸出你的實體類。
1、映射數據庫
映射數據庫主要通過Database屬性來指定,引用命名空間System.Data.Linq.Mapping;
具體看如下代碼:
//這里在連接的時候 如果MyDatabase不指定Database屬性,生成的數據庫名為MyDbContext類名//如果指定,則為Database屬性里的名稱,在這里生成的數據庫名為IThinks[Database(Name = "IThinks")]public class MyDbContext : DataContext{//必須構建此表,不然創建數據庫時會提示沒有表,無法創建。public Table<LoginUser> LoginUsers;public Table<UserBaseInfo> UserBaseInfos;public Table<Aritcal> Articals;public MyDbContext(string connection) : base(connection){}}然后再創建數據庫連接的時候,就可以這樣寫,如果database 不設置的話,默認的數據庫名就會為MyDbContext 類名:
MyDbContext db = new MyDbContext("Data Source=localhost;Integrated Security=true;");這樣的話,輸出的連接sql語句為:
2、映射表
映射表使用的attribute屬性為Table
//Table:映射數據庫中對應表或視圖名,NAME指定數據庫表名,若無此表,創建數據庫時,會自動創建 [Table(Name="UserBaseInfo")]public class UserBaseInfo3、映射列
映射列使用的attribute屬性為Column,參數設置比較多,具體看如下代碼:
//Column:映射數據庫表中字段 其特性為://Name:數據庫中列的名稱//DbType:數據庫列的數據庫類型//Storage:獲取或設置私有存儲字段以保存列值//IsPrimaryKey:指示所關聯的列是否是相應表的主鍵 默認false//CanBeNull:指示所關聯的列能否包含空值 //CanBeNull不能亂用,如果某列CanBeNull設置為true,但從數據庫中查出來的值為null的話, //這一列在update的時候會提示找不到此行或行已更改,因為其查詢的語句為where 0 = 1 所以找不到 //可以查看:http://stackoverflow.com/questions/2275442/linq-update-query-generates-where-0-1//如果你非要設置canbenull=true,可以通過繼續設置其updatecheck為never或whenchanged來規避where 0=1這個問題。//AutoSync:在執行insert或者update操作之后獲取列值,默認為never;//UpdateCheck:即設置是否檢查沖突,默認是Always//IsDbGenerated=true 是否數據庫自動生成值,如果設置為true的話,那么在實例化實體給此列賦值將會無效,在執行插入時,會傳值為null進入 //如果這時候數據庫未給予默認值或值自增設置,則會報此字段為空的錯誤,雖然你在實例化時已經賦值。 [Column(DbType = "int", IsPrimaryKey = true, IsDbGenerated = true)]public int UserID { get; set; }[Column(DbType = "nvarchar(50) not null", CanBeNull = false, UpdateCheck = UpdateCheck.WhenChanged)]public string UserName { get; set; }[Column(DbType = "nvarchar(50)", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]public string UserNickName { get; set; }4、映射關系
這里的關系是指的數據庫中一對多和一對一。主鍵基表和外鍵基表的設置也能通過實體字段的Association屬性(IsForeignKey=true)來進行關聯,從而在創建數據庫時,自動創建表之間的關系。
但要結合EntityRef<T>或 EntitySet<T> 來定義并表示一個關系
EntityRef代表一對多關系中的單一實例方,EntitySet主要代表一對多和一對一關系中的集合方,下面分別用代碼介紹
以用戶基本信息表 UserBaseInfo和用戶文章表Aritcal來作為介紹,他們是一對多的關系
1)EntityRef+Association的使用
因為EntityRef代表的是1:M關系中的1,所以它應該為Aritcal實體的成員,泛型對象為UserBaseInfo
這里UserBaseInfo的實體和Artical實體分別為:
//Table:映射數據庫中對應表或視圖名,若無此表,會自動創建 [Table(Name = "UserBaseInfo")]public class UserBaseInfo{ [Column(DbType = "int", IsPrimaryKey = true, IsDbGenerated = true)]public int UserID { get; set; }[Column(DbType = "nvarchar(50) not null", CanBeNull = false, UpdateCheck = UpdateCheck.WhenChanged)]public string UserName { get; set; } private EntitySet<Aritcal> _Artiacle;[Association(ThisKey = "UserID", OtherKey = "UserID")]public EntitySet<Aritcal> Articals{get { return _Artiacle; }set { _Artiacle.Assign(value); }}} [Table(Name = "Artical")]public class Aritcal{[Description("文章ID"), Column(IsPrimaryKey = true, CanBeNull = false, DbType = "int not null")]public int ArticalID { get; set; }[Description("用戶ID"), Column(CanBeNull = false, DbType = "int not null")]public int UserID { get; set; }[Description("文章標題"), Column(DbType = "nvarchar(100) not null", UpdateCheck = UpdateCheck.Never)]public string ArticalTitle { get; set; }[Description("文章分類"), Column(DbType = "int not null", UpdateCheck = UpdateCheck.Never)]public int CategoryID { get; set; }[Description("模塊分類"), Column(DbType = "int", UpdateCheck = UpdateCheck.Never)]public int ModuleID { get; set; }[Description("文章內容"), Column(DbType = "ntext not null", UpdateCheck = UpdateCheck.Never)]public string Content { get; set; } private EntityRef<UserBaseInfo> _UserBaseInfo;//Name:外鍵名//ThisKey:外鍵表的外鍵列 可以不為主鍵 除非1:1關系中//OtherKey:主鍵表的主鍵列 必須是主鍵//IsForeignKey:是否外鍵//Storage:用來存儲的變量[Association(Name = "FK_Aritcal_UserBaseInfo_UserID", ThisKey = "UserID", OtherKey = "UserID", IsForeignKey = true, Storage = "_UserBaseInfo")]public UserBaseInfo UserBaseInfo{get { return _UserBaseInfo.Entity; }set { _UserBaseInfo.Entity = value; }}}這樣Artical自動創建外鍵,生成的表結構關系為
2)下面在講下EntitySet<T> 和Association
在UserBaseInfo表中創建下面成員,這樣做的好處是,進行數據庫關聯查詢時便能查詢出數據
private EntitySet<Aritcal> _Artiacle;[Association(ThisKey = "UserID", OtherKey = "UserID")]public EntitySet<Aritcal> Articals{get { return _Artiacle; }set { _Artiacle.Assign(value); }} 見查詢代碼: 查詢用戶信息表中用戶ID為1的用戶信息,通過調用Articals成員,自動關聯查詢出用戶id為1的文章列表 UserBaseInfo userbase = db.GetTable<UserBaseInfo>().Where(a => a.UserID == 1).FirstOrDefault();foreach (Aritcal artical in userbase.Articals.ToList()){Console.WriteLine(string.Format("userid:{0} aritical userid:{1} articalid:{2} ispublist{3}",userbase.UserID, artical.UserID, artical.ArticalID, artical.IsPublish));}查詢結果如下:
5、映射存儲過程
通過調用Function屬性實現調用存儲過程,只有一個Name特性,來指定存儲過程的名稱
如下面的實例通過用戶名ID,獲取用戶的密碼:
首先創建存儲過程
create procedure [dbo].[GetPassword] (@userid int , @password nvarchar(30) output ) as begin select @password = c.Password from LoginUser c where c.UserID=@userid end /// <summary>/// 獲取用戶密碼/// </summary>/// <param name="userid">用戶名ID</param>/// <param name="password">用來返回獲取到的密碼</param>/// <returns></returns>[Function(Name = "GetPassword")]public int GetPassword([Parameter(DbType = "int")] int userid, [Parameter(DbType = "nvarchar(30)")] out string password){password = "";IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)MethodInfo.GetCurrentMethod()), userid, password);password = (string)result.GetParameterValue(1); //返回需要的密碼數據 必須用out 或者ref引用,不然得到空值return (int)result.ReturnValue; //這里返回0 表示執行成功}調用代碼如下:
string str;db.GetPassword(userbase.UserID, out str);Console.WriteLine("pwd:"+str);調用結果如下:
6、映射函數
用戶自定義函數(UDF)在linq to sql中用到的屬性是一樣的,不過函數和存儲過程的區別導致了函數只能返回單個值,而不能像存儲過程那樣返回多個參數
具體實現看如下代碼
首先在數據庫中定義函數
--創建通過用戶ID獲取密碼的函數 create function Fun_GetPassword (@userid int ) returns nvarchar(30) as begin declare @password nvarchar(30) select @password = c.Password from LoginUser c where c.UserID=@useridreturn @password end然后在vs中編寫代碼調用
//調用函數 這里要加dbo.,不然你若返回的不是表,則會提示Fun_GetPassword不是可以識別的 內置函數名稱。//另外調用函數,要定義IsComposable特性為true,這樣他才知道是調用的存儲過程[Function(Name = "dbo.Fun_GetPassword", IsComposable = true)]public string Fun_GetPassword([Parameter(DbType = "int")] int userid){IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)MethodInfo.GetCurrentMethod()), userid);return (string)result.ReturnValue;}//調用自定義函數 獲取密碼string mypwd= db.Fun_GetPassword(userbase.UserID);Console.WriteLine("pwd:"+mypwd);調用結果如下:
下載源碼
您的支持是我最大的動力,喜歡就點推薦吧!!!
轉載于:https://www.cnblogs.com/flowwind/p/3307373.html
總結
以上是生活随笔為你收集整理的讲讲Linq to SQL映射(基础篇)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 闺蜜网名韩文一对133个
- 下一篇: 处理高像素的照片