那天有个小孩跟我说LINQ(五)转载

2  LINQ TO SQL(代码下载)

     我们以一个简单的销售的业务数据库为例子

        表结构很简单:Users(购买者(用户)表),Products(产品信息表),Sales(销售表),ReturnSales(退货信息表)

那天有个小孩跟我说LINQ(五)转载在Sales表中,我们就知道谁买的了(根据UserId),然后买的时间,买的产品(根据ProductCode),Sales和ReturnSales一样的结构的

接下来我们按照 小孩LINQ(四)中的方法建立好dbml文件,以便好操作数据。

准备工作后完成后如下:

那天有个小孩跟我说LINQ(五)转载

附一(数据库代码):

USE [master]
GO
/****** Object:  Database [SalesDB]    Script Date: 04/08/2013 21:44:07 ******/
CREATE DATABASE [SalesDB] ON  PRIMARY 
( NAME = N'SalesDB', FILENAME = N'D:\linq\linq_Ch5\DB\SalesDB.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'SalesDB_log', FILENAME = N'D:\linq\linq_Ch5\DB\SalesDB_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [SalesDB] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [SalesDB].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [SalesDB] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [SalesDB] SET ANSI_NULLS OFF
GO
ALTER DATABASE [SalesDB] SET ANSI_PADDING OFF
GO
ALTER DATABASE [SalesDB] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [SalesDB] SET ARITHABORT OFF
GO
ALTER DATABASE [SalesDB] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [SalesDB] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [SalesDB] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [SalesDB] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [SalesDB] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [SalesDB] SET CURSOR_DEFAULT  GLOBAL
GO
ALTER DATABASE [SalesDB] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [SalesDB] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [SalesDB] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [SalesDB] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [SalesDB] SET  DISABLE_BROKER
GO
ALTER DATABASE [SalesDB] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [SalesDB] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [SalesDB] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [SalesDB] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [SalesDB] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [SalesDB] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [SalesDB] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [SalesDB] SET  READ_WRITE
GO
ALTER DATABASE [SalesDB] SET RECOVERY FULL
GO
ALTER DATABASE [SalesDB] SET  MULTI_USER
GO
ALTER DATABASE [SalesDB] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [SalesDB] SET DB_CHAINING OFF
GO
EXEC sys.sp_db_vardecimal_storage_format N'SalesDB', N'ON'
GO
USE [SalesDB]
GO
/****** Object:  Table [dbo].[Users]    Script Date: 04/08/2013 21:44:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Users](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserName] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Sales]    Script Date: 04/08/2013 21:44:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Sales](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ProductCode] [nvarchar](50) NOT NULL,
    [Quantity] [int] NOT NULL,
    [UserId] [int] NOT NULL,
    [CreateDate] [datetime] NOT NULL,
 CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[ReturnSales]    Script Date: 04/08/2013 21:44:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ReturnSales](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ProductCode] [nvarchar](50) NOT NULL,
    [Quantity] [int] NOT NULL,
    [UserId] [int] NOT NULL,
    [CreateDate] [datetime] NOT NULL,
 CONSTRAINT [PK_ReturnSales] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Products]    Script Date: 04/08/2013 21:44:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Products](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ProductCode] [nvarchar](50) NOT NULL,
    [ProductName] [nvarchar](50) NOT NULL,
    [ProductUnitPrice] [decimal](18, 2) NOT NULL,
    [ProductType] [smallint] NOT NULL,
    [ProductDescription] [nvarchar](200) NOT NULL,
 CONSTRAINT [PK_Products] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Default [DF_Sales_CreateDate]    Script Date: 04/08/2013 21:44:09 ******/
ALTER TABLE [dbo].[Sales] ADD  CONSTRAINT [DF_Sales_CreateDate]  DEFAULT (getdate()) FOR [CreateDate]
GO
/****** Object:  Default [DF_ReturnSales_CreateDate]    Script Date: 04/08/2013 21:44:09 ******/
ALTER TABLE [dbo].[ReturnSales] ADD  CONSTRAINT [DF_ReturnSales_CreateDate]  DEFAULT (getdate()) FOR [CreateDate]
GO
/****** Object:  Default [DF_Products_ProductName]    Script Date: 04/08/2013 21:44:09 ******/
ALTER TABLE [dbo].[Products] ADD  CONSTRAINT [DF_Products_ProductName]  DEFAULT ('') FOR [ProductName]
GO

2.1 检测数据库是否存在

     代码如下:

   1:     string conStr = @"Data Source=.;Initial Catalog=SalesDB;Integrated Security=True"; //复制于app.config文件中的
   2:              //1.检测数据库是否存在
   3:              SalesDBDataContext db = new SalesDBDataContext(conStr);
   4:              if (db.DatabaseExists())
   5:              {
   6:                  Console.WriteLine("数据库存在!");
   7:              }
   8:              else {
   9:                  Console.WriteLine("可惜啊,数据库不存在!");
  10:              }

效果图:

那天有个小孩跟我说LINQ(五)转载

 

2.2 插入数据(我们创建后面例子的基础)

为了不影响后面的代码,我们将2.1例子的代码注释掉,然后项目中新建一个Enum文件夹

①向Products表中插入几条数据,然后Users表中创建几个用户,然后添加几条Sales信息和ReturnSales信息

    我们使用 InsertOnSubmit 方法

    产品类型枚举(ProductTypeEnum.cs)如下:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:   
   6:  namespace linq_Ch5.Enum
   7:  {
   8:      public enum ProductTypeEnum
   9:      {
  10:          HuaZhuang=1,
  11:          Books=2,
  12:          Computers=3,
  13:          Phones=4,
  14:          Bags=5,
  15:          Clothes=6
  16:      }
  17:  }

    Program.cs代码如下(先Products产品):

   1:           SalesDBDataContext db = new SalesDBDataContext();
   2:              Products pro1 = new Products
   3:              {
   4:                  ProductName = "相宜本草男士专用洗面奶",
   5:                  ProductCode = "XYBCNSZYXMN",
   6:                  ProductType = (int)ProductTypeEnum.HuaZhuang,
   7:                  ProductDescription = "祛痘效果很好",
   8:                  ProductUnitPrice = 39.9M
   9:              };
  10:              Products pro2 = new Products
  11:              {
  12:                  ProductName = "相宜本草男士专用爽肤水",
  13:                  ProductCode = "XYBCNSZYSFS",
  14:                  ProductType = (int)ProductTypeEnum.HuaZhuang,
  15:                  ProductDescription = "去除倦容",
  16:                  ProductUnitPrice = 80.0M
  17:              };
  18:              Products pro3 = new Products
  19:              {
  20:                  ProductName = "Windows Phone7 程序设计",
  21:                  ProductCode = "WP7CXSJ",
  22:                  ProductType = (int)ProductTypeEnum.Books,
  23:                  ProductDescription = "wp7开发必备",
  24:                  ProductUnitPrice = 99.00M
  25:              };
  26:              Products pro4 = new Products
  27:              {
  28:                  ProductName = "ASP.NET MVC4 IN ACTION",
  29:                  ProductCode = "ANMVC4IA",
  30:                  ProductType = (int)ProductTypeEnum.Books,
  31:                  ProductDescription = "最新的ASP.NET MVC入门资料",
  32:                  ProductUnitPrice = 198.00M
  33:              };
  34:              Products pro5 = new Products
  35:              {
  36:                  ProductName = "韩国最新迷你小夹克",
  37:                  ProductCode = "HGZXMNXJK",
  38:                  ProductType = (int)ProductTypeEnum.Clothes,
  39:                  ProductDescription = "男士修身的",
  40:                  ProductUnitPrice = 298.00M
  41:              };
  42:              Products pro6 = new Products
  43:              {
  44:                  ProductName = "达普斯女生气质包包",
  45:                  ProductCode = "DPSNSQZBB",
  46:                  ProductType = (int)ProductTypeEnum.Bags,
  47:                  ProductDescription = "目前只有海蓝色的",
  48:                  ProductUnitPrice = 98.00M
  49:              };
  50:              Products pro7 = new Products
  51:              {
  52:                  ProductName = "海澜之家新款A8484",
  53:                  ProductCode = "HNZJA8484",
  54:                  ProductType = (int)ProductTypeEnum.Clothes,
  55:                  ProductDescription = "最显男人气质的衣服",
  56:                  ProductUnitPrice = 498.00M
  57:              };
  58:              Products pro8 = new Products
  59:              {
  60:                  ProductName = "Iphone5 国行版",
  61:                  ProductCode = "IPHONE5",
  62:                  ProductType = (int)ProductTypeEnum.Phones,
  63:                  ProductDescription = "美版的4688人民币",
  64:                  ProductUnitPrice = 5498.00M
  65:              };
  66:              List<Products> products = new List<Products> { 
  67:                  pro1,
  68:                  pro2,
  69:                  pro3,
  70:                  pro4,
  71:                  pro5,
  72:                  pro6,
  73:                  pro7,
  74:                  pro8,
  75:              };
  76:              foreach (Products itemPro in products)
  77:              {
  78:                  db.Products.InsertOnSubmit(itemPro);
  79:              }
  80:              db.SubmitChanges();
  81:              Console.WriteLine("product表数据添加成功!");

效果图:

那天有个小孩跟我说LINQ(五)转载

Program.cs代码如下(再Users用户表,使用InsertAllOnSubmit):

   1:    List<Users> users = new List<Users> { 
   2:                  new Users{UserName="茗洋"},
   3:                  new Users{UserName="芳竹"},
   4:                  new Users{UserName="清新空气"}
   5:              };
   6:              db.Users.InsertAllOnSubmit(users);
   7:              db.SubmitChanges();
   8:              Console.WriteLine("用户信息添加成功");

效果图:

那天有个小孩跟我说LINQ(五)转载

同理,完成Sales和ReturnSales表的数据

   1:    List<Sales> sales = new List<Sales> { 
   2:                new Sales{ProductCode="XYBCNSZYXMN",Quantity=10,UserId=1,CreateDate=DateTime.Now},
   3:                new Sales{ProductCode="XYBCNSZYSFS",Quantity=8,UserId=1,CreateDate=DateTime.Now},
   4:                new Sales{ProductCode="XYBCNSZYSFS",Quantity=8,UserId=2,CreateDate=DateTime.Now},
   5:                new Sales{ProductCode="XYBCNSZYXMN",Quantity=1,UserId=2,CreateDate=DateTime.Now},
   6:   
   7:                new Sales{ProductCode="WP7CXSJ",Quantity=1,UserId=3,CreateDate=DateTime.Now},
   8:                new Sales{ProductCode="WP7CXSJ",Quantity=100,UserId=2,CreateDate=DateTime.Now},
   9:                new Sales{ProductCode="ANMVC4IA",Quantity=1,UserId=3,CreateDate=DateTime.Now},
  10:                new Sales{ProductCode="HGZXMNXJK",Quantity=1,UserId=2,CreateDate=DateTime.Now},
  11:   
  12:                new Sales{ProductCode="DPSNSQZBB",Quantity=1,UserId=2,CreateDate=DateTime.Now},
  13:                new Sales{ProductCode="HNZJA8484",Quantity=1,UserId=1,CreateDate=DateTime.Now},
  14:                new Sales{ProductCode="ANMVC4IA",Quantity=1,UserId=1,CreateDate=DateTime.Now},
  15:                new Sales{ProductCode="IPHONE5",Quantity=1,UserId=3,CreateDate=DateTime.Now}
  16:              };
  17:   
  18:              List<ReturnSales> returnSales = new List<ReturnSales> { 
  19:                new ReturnSales{ProductCode="XYBCNSZYXMN",Quantity=1,UserId=1,CreateDate=DateTime.Now},
  20:                new ReturnSales{ProductCode="XYBCNSZYSFS",Quantity=8,UserId=1,CreateDate=DateTime.Now},
  21:                new ReturnSales{ProductCode="XYBCNSZYSFS",Quantity=8,UserId=2,CreateDate=DateTime.Now},
  22:                new ReturnSales{ProductCode="WP7CXSJ",Quantity=50,UserId=2,CreateDate=DateTime.Now}
  23:              };
  24:              db.Sales.InsertAllOnSubmit<Sales>(sales);
  25:              db.ReturnSales.InsertAllOnSubmit<ReturnSales>(returnSales);
  26:              db.SubmitChanges();
  27:              Console.WriteLine("添加 sale表和returnSales表信息成功!");
 

2.3 修改数据

    获得数据后,修改其中的属性,然后SubmitChanges(),就修改了

    代码如下:

   1:   Products pro9 = new Products
   2:              {
   3:                  ProductName = "开心的哇哇",
   4:                  ProductCode = "KXDWW",
   5:                  ProductType = (int)ProductTypeEnum.Clothes,
   6:                  ProductDescription = "能听懂人说话",
   7:                  ProductUnitPrice = 148M
   8:              };
   9:              db.Products.InsertOnSubmit(pro9);
  10:              db.SubmitChanges();
  11:              Products getWaWa = db.Products.FirstOrDefault(x => x.ProductCode == "KXDWW");
  12:              Console.WriteLine("添加成功!商品名为" + getWaWa.ProductName);
  13:              Console.WriteLine("正在修改名称...");
  14:              getWaWa.ProductName = "开心的娃娃";
  15:              db.SubmitChanges();
  16:              Products getWaWaUpdate = db.Products.FirstOrDefault(x => x.ProductCode == "KXDWW");
  17:              Console.WriteLine("修改成功!修改后的商品名为" + getWaWaUpdate.ProductName);

效果图:

那天有个小孩跟我说LINQ(五)转载那天有个小孩跟我说LINQ(五)转载

 

2.4 删除数据

代码如下:

   1:          #region 删除数据
   2:              //获得数据后删除
   3:               Products delWaWa = db.Products.FirstOrDefault(x => x.ProductCode == "KXDWW");
   4:               db.Products.DeleteOnSubmit(delWaWa);
   5:               db.SubmitChanges();
   6:               Console.WriteLine("删除成功!");
   7:              #endregion

效果图:

那天有个小孩跟我说LINQ(五)转载

批量删除

   1:        Products pro10 = new Products
   2:            {
   3:                ProductName = "开心的哇哇测试1",
   4:                ProductCode = "KXDWW1",
   5:                ProductType = (int)ProductTypeEnum.Clothes,
   6:                ProductDescription = "能听懂人说话",
   7:                ProductUnitPrice = 148M
   8:            };
   9:               db.Products.InsertOnSubmit(pro10);
  10:               Products pro11 = new Products
  11:               {
  12:                   ProductName = "开心的哇哇测试2",
  13:                   ProductCode = "KXDWW2",
  14:                   ProductType = (int)ProductTypeEnum.Clothes,
  15:                   ProductDescription = "能听懂人说话",
  16:                   ProductUnitPrice = 148M
  17:               };
  18:               db.Products.InsertOnSubmit(pro11);
  19:               db.SubmitChanges();
  20:               Console.WriteLine("添加测试数据成功");
  21:              //获得数据
  22:               Console.WriteLine("开始获得数据");
  23:               IEnumerable<Products> pros = db.Products.Where(p => p.ProductCode == "KXDWW1" || p.ProductCode == "KXDWW2").ToList();
  24:               Console.WriteLine("获得刚刚添加的数据成功");
  25:               db.Products.DeleteAllOnSubmit(pros);
  26:               db.SubmitChanges();
  27:               Console.WriteLine("删除成功");

效果图:

那天有个小孩跟我说LINQ(五)转载

 

2.5 差集,交集,并集操作

      ①差集,取从未有过退货记录的产品信息

         代码:

   1:  var saleInfo = db.Sales.Select(itm => new { itm.ProductCode });
   2:                  var returnSaleInfo = db.ReturnSales.Select(itm => new { itm.ProductCode });
   3:                  var query = saleInfo.Except(returnSaleInfo); //参数的顺序有关,except的左边为总集,右边为在saleInfo中查找匹配的
   4:                  foreach (var item in query)
   5:                  {
   6:                      Console.WriteLine(item.ProductCode+",");
   7:                  }
   8:                  Console.WriteLine();

       ②交集,取有过退货记录的产品信息

         代码:

   1:   var saleInfo2 = db.Sales.Select(itm => new { itm.ProductCode });
   2:                  var returnSaleInfo2 = db.ReturnSales.Select(itm => new { itm.ProductCode });
   3:                  var query2 = saleInfo.Intersect(returnSaleInfo); 
   4:                  foreach (var item in query2)
   5:                  {
   6:                      Console.WriteLine(item.ProductCode + ",");
   7:                  }
   8:                  Console.WriteLine();

     ③并集,查询每种产品的销售总数

         我们先创建两个视图 V_SalesInfo(Products和Sales关联),V_ReturnSalesInfo(Products和ReturnSales关联)

         V_SalesInfo

SELECT     p.ProductCode, p.ProductName, s.ProductCode AS PRC, p.ProductUnitPrice, p.ProductType, p.ProductDescription, s.Quantity, s.UserId, s.CreateDate
FROM         dbo.Products AS p INNER JOIN
                      dbo.Sales AS s ON p.ProductCode = s.ProductCode

         V_ReturnSalesInfo

   1:  SELECT     p.ProductCode, p.ProductName, s.ProductCode AS PRC, p.ProductUnitPrice, p.ProductType, p.ProductDescription, s.Quantity, s.UserId, s.CreateDate
   2:  FROM         dbo.Products AS p INNER JOIN
   3:                        dbo.ReturnSales AS s ON p.ProductCode = s.ProductCode

将视图拖放到dbml文件中        

代码:

   1:     var saInfo = from si in db.V_SalesInfo
   2:                           select new { si.ProductCode, si.ProductName, si.Quantity };
   3:              var reSaInfo = from rs in db.V_ReturnSalesInfo
   4:                           select new { rs.ProductCode, rs.ProductName, Quantity=rs.Quantity*(-1) };
   5:              var salesInfo = saInfo.Union(reSaInfo);
   6:              var queryUnion = from item in salesInfo
   7:                               group item by new { item.ProductCode, item.ProductName } into g
   8:                               select new
   9:                               {
  10:                                   产品代码 = g.Key.ProductCode,
  11:                                   产品名称 = g.Key.ProductName,
  12:                                   销售总数 = g.Sum(i => i.Quantity)
  13:                               };
  14:              foreach (var unionItem in queryUnion)
  15:              {
  16:                  Console.WriteLine("产品代码:" + unionItem.产品代码 + "  " + "产品名称:" + unionItem.产品名称 + "销售总数:" + unionItem.销售总数);
  17:              }

效果图:

那天有个小孩跟我说LINQ(五)转载

 

2.6 执行SQL

①查询

          string sql = "select * from V_SalesInfo where ProductCode='" + "IPHONE5" + "'";
            var query10 = db.ExecuteQuery<V_SalesInfo>(sql);
            foreach (var unionItem in query10)
            {
                Console.WriteLine("产品代码:" + unionItem.ProductCode + "  " + "产品名称:" + unionItem.ProductName + "销售总数:" + unionItem.Quantity);
            }

      效果图:

那天有个小孩跟我说LINQ(五)转载

②删除

string sql2 = "delete from ReturnSales where ProductCode ='" + "WP7CXSJ" + "'";
            db.ExecuteCommand(sql2);
            Console.WriteLine("sql方式删除成功");

      效果图:

那天有个小孩跟我说LINQ(五)转载

③修改和添加 请参考②练习

④获得已更新的对象 GetChangeSet()

        使用LINQ to SQL操作数据库,在调用数据上下文类(DataContext)的SubmitChange()方法将所有的更新提交到数据库之前,有时需要获取已更新的对象,这样做对于日志和调试都是很有用的。

   1:       foreach (var item in db.Sales)
   2:              {
   3:                  item.CreateDate = DateTime.Now;
   4:              }
   5:              //获得被修改的记录
   6:              ChangeSet set = db.GetChangeSet();
   7:              IList<object> sa=set.Updates;
   8:              foreach (var item in sa)
   9:              {
  10:                  Sales sal = item as Sales;
  11:                  Console.WriteLine("产品编号:"+sal.ProductCode+"  "+sal.CreateDate.ToString("yyyy年MM月dd日"));
  12:              }

效果图:

那天有个小孩跟我说LINQ(五)转载

上一篇:MySQL数据库主从复制实践


下一篇:thinkphp-模板输出变量使用函数