zoukankan      html  css  js  c++  java
  • 轻量ORM-SqlRepoEx (十五)最佳实践之数据映射(Map)

    简介:SqlRepoEx是 .Net平台下兼容.NET Standard 2.0人一个轻型的ORM。解决了Lambda转Sql语句这一难题,SqlRepoEx使用的是Lambda表达式,所以,对c#程序员来说,是非常简单的,其语法特点与Linq to Sql极为相似。不仅实现了完整的Select、Insert、Update、Delete等语句解析器,同时,也实现了Select、where、order by等子句,这些语句与子句均支持导出SQL语句,使得拼接复杂场景SQL语句变得轻松,SqlRepoEx很快其原生数据访问与Dapper不相上下,SqlRepoEx本身支持Sql Server与MySql方言,同时通过SqlRepoEx.Normal支持非方言SQL。SqlRepoEx没侵入性,仅通过简单的几个特性,就能让类与数据库关联起来;

     

    *本系列以静态工厂为例;

    *数据来源于Northwind数据库;

    *完整的代码见 https://github.com/AzThinker/SqlRepoEx2.0StartGuid  https://gitee.com/azthinker/SqlRepoEx2.0StartGuid

     

    1、从 SqlRepoEx 2.2.1 起,标识数据据字段的特性标识改为使用System.ComponentModel.DataAnnotations中的声明,降低使用难度,当然 SqlRepoEx 中自定义的特性依然是支持的。

    2、只有以类属性定义的,才能作为数据字段使用, SqlRepoEx 只反身属性。

    3、SqlRepoEx 不使用XML文件来映射关系

     

    一、表名

    1、如果不使用任何特性, SqlRepoEx会将当前类名当成数名。

    如:

     public sealed class AzProducts

        {

        ...

        }

        会返回形如  select ...  from AzProducts

        显然,AzCategories在数据库中不存在,当然,如果类名与数据库中对应的表名一至,是可以不用标识的。

     

      2、使用 Table 特性,定义在System.ComponentModel.DataAnnotations中

    [Table("Products")]

     public sealed class AzProducts

        {

        ...

        }

     会返回形如  select ...  from Products

     

     3、使用 TableName特性,定义在SqlRepoEx.Core.CustomAttribute中

    [TableName("Products")]

     public sealed class AzProducts

        {

    ...

        }

     同样会返回形如  select ...  from Products

     当然,使用哪种,按各自的喜好

     

     二、关键字段

     1、如果未使用任何特性,在使用,For() 方法时,不会自动的产生Where条件语句。

        [Table("Products")]

        public sealed class AzProducts

        {

    public int ProductID { get; set; }

    ...

        }

     当使用

     AzProducts azProducts = new AzProducts { ProductName2 = "testvalue", ProductID = 82 };

    var resultUpdate = repository.Delete().For(azProducts);

    只会产生

    DELETE [dbo].[Products]

    当然,这不所期望的

     

      2、使用 Key 特性 Table 定义在System.ComponentModel.DataAnnotations中

    [Table("Products")]

     public sealed class AzProducts

        {

    [Key]

    public int ProductID { get; set; }

    ...

        }

     会返回形如 DELETE [dbo].[Products] WHERE  [ProductID] = 82;

     

     3、使用 KeyField 特性 Table定义在SqlRepoEx.Core.CustomAttribute中

    [TableName("Products")]

     public sealed class AzProducts

        {

     [KeyField]

     public int ProductID { get; set; }

    ...

        }

     同样会返回形如 DELETE [dbo].[Products] WHERE  [ProductID] = 82;

     

    三、标识字段(自增字段)

     1、如果未使用任何特性,在使用,For() 方法时,在增加操作时,不会返回自增自段的实际值。

        [Table("Products")]

        public sealed class AzProducts

        {

    public int ProductID { get; set; }

    ...

        }

     当使用

    AzProducts azProducts = new AzProducts { ProductName2 = "testvalue" };

                var resultinsert = repository

                                        .Insert()

                                        .For(azProducts);

    只会产生

    INSERT [dbo].[Products]([ProductName],[SupplierID],[CategoryID],[QuantityPerUnit],[UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued])

    VALUES('testvalue',NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);

     

      2、使用 DatabaseGenerated 特性,定义在System.ComponentModel.DataAnnotations中

    [Table("Products")]

     public sealed class AzProducts

        {

    [Key]

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

    public int ProductID { get; set; }

    ...

        }

     会返回形如

    INSERT [dbo].[Products]([ProductName],[SupplierID],[CategoryID],[QuantityPerUnit],[UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued])

    VALUES('testvalue',NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);

    SELECT [ProductID],[ProductName] as ProductName2,[SupplierID],[CategoryID],[QuantityPerUnit],[UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued]

    FROM [dbo].[Products]

    WHERE [ProductID] = SCOPE_IDENTITY();

     

     3、使用 IdentityField 特性,定义在SqlRepoEx.Core.CustomAttribute中

    [TableName("Products")]

     public sealed class AzProducts

        {

    [KeyField]

    [IdentityField]

    public int ProductID { get; set; }

     ...

        }

     同样会返回形如

    INSERT [dbo].[Products]([ProductName],[SupplierID],[CategoryID],[QuantityPerUnit],[UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued])

    VALUES('testvalue',NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);

    SELECT [ProductID],[ProductName] as ProductName2,[SupplierID],[CategoryID],[QuantityPerUnit],[UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued]

    FROM [dbo].[Products]

    WHERE [ProductID] = SCOPE_IDENTITY();

     

    四、非字段属性

    1、如果未使用任何特性,如下面属性 public string Supplier { get; set; }。此属性在数据库中无对应的字段

        [Table("Products")]

        public sealed class AzProducts

        {

    [Key]

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

    public int ProductID { get; set; }

    public string Supplier { get; set; }

    ...

        }

     当使用

    var result = repository.Query();

    会产生形如

    select ProductID,Supplier ....

     

      2、使用 NotMapped 特性,定义在System.ComponentModel.DataAnnotations中

    [Table("Products")]

     public sealed class AzProducts

        {

    [Key]

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

    public int ProductID { get; set; }

    [NotMapped]

    public string Supplier { get; set; }

     ...

        }

     当使用

    var result = repository.Query();

    时,Supplier 不会出现在查询语句中,但要注意,当使用选择器来查询时,何然会出现在Select语句中;

    如 var result = repository.Query().Select(c=>c.ProductID,c=>c.Supplier);

     

     3、使用 NonDatabaseField 特性,定义在SqlRepoEx.Core.CustomAttribute中

    [TableName("Products")]

     public sealed class AzProducts

        {

    [Key]

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

    public int ProductID { get; set; }

    [NonDatabaseField]

    public string Supplier { get; set; }

     ...

        }

     当使用

    var result = repository.Query();

    时,Supplier 不会出现在查询语句中,但要注意,当使用选择器来查询时,何然会出现在Select语句中;

    如 var result = repository.Query().Select(c=>c.ProductID,c=>c.Supplier);

     

    五、指定属性对应的数据库字段名

    有时,类属性名与数据库中的字段名不完全是一一对应的,所以需要指定实际字段名

    使用 Column 特性,定义在System.ComponentModel.DataAnnotations中,SqlRepoEx中没有对应的特性。

    如下列类中的  ProductName2 属性,对应的数据库字段实为 ProductName

    [TableName("Products")]

     public sealed class AzProducts

        {

    [Key]

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

    public int ProductID { get; set; }

    [NonDatabaseField]

    public string Supplier { get; set; }

    [Column("ProductName")]

     public string ProductName2 { get; set; }

             ...

        }

     

  • 相关阅读:
    使用libmap
    仿真 vcs/ncverilog
    git——git不常见指令记录
    Mac更换鼠标指针样式_ANI、CUR文件解析
    油猴脚本——CSDN防复制破解
    解决Establishing SSL connection without server‘s identity verification is not recommended.
    IDEA激活 试用30天 自动激活
    IDEA Plugins:Free Mybatis plugin(Mapper跳转XML)安装及使用
    Springboot异常汇总
    springbootdemo
  • 原文地址:https://www.cnblogs.com/athinker/p/9846256.html
Copyright © 2011-2022 走看看