广告位联系
返回顶部
分享到

C#内置泛型委托之Func委托介绍

C#教程 来源:互联网 作者:秩名 发布时间:2022-03-14 09:22:09 人浏览
摘要

一、什么是Func委托 Func委托代表有返回类型的委托 二、Func委托定义 查看Func的定义: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 using System.Runtime.CompilerServices; namespa

一、什么是Func委托

Func委托代表有返回类型的委托

二、Func委托定义

查看Func的定义:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

using System.Runtime.CompilerServices;

 

namespace System

{

    //

    // 摘要:

    //     封装一个方法,该方法具有两个参数,并返回由 TResult 参数指定的类型的值。

    //

    // 参数:

    //   arg1:

    //     此委托封装的方法的第一个参数。

    //

    //   arg2:

    //     此委托封装的方法的第二个参数。

    //

    // 类型参数:

    //   T1:

    //     此委托封装的方法的第一个参数的类型。

    //

    //   T2:

    //     此委托封装的方法的第二个参数的类型。

    //

    //   TResult:

    //     此委托封装的方法的返回值类型。

    //

    // 返回结果:

    //     此委托封装的方法的返回值。

    [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]

    public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);

}

你会发现,Func其实就是有多个输出参数并且有返回值的delegate。

3、示例

Func至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须有返回值,不可void。

Func<int> 表示没有输入参参,返回值为int类型的委托。

Func<object,string,int> 表示传入参数为object, string ,返回值为int类型的委托。

Func<object,string,int> 表示传入参数为object, string, 返回值为int类型的委托。

Func<T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型),返回值为int类型的委托。

代码示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace FunDemo

{

    class Program

    {

        static void Main(string[] args)

        {

            // 无参数,只要返回值

            Func<int> fun1 = new Func<int>(FunWithNoPara);

            int result1= fun1();

            Console.WriteLine(result1);

            Console.WriteLine("----------------------------");

            Func<int> fun2 = delegate { return 19; };

            int result2 = fun2();

            Console.WriteLine(result2);

            Console.WriteLine("----------------------------");

            Func<int> fun3 = () => { return 3; };

            int result3 = fun3();

            Console.WriteLine(result3);

            Console.WriteLine("----------------------------");

            //有一个参数,一个返回值

            Func<int, int> fun4 = new Func<int, int>(FunWithPara);

            int result4 = fun4(4);

            Console.WriteLine($"这里是一个参数一个返回值的方法,返回值是:{result4}");

            Console.WriteLine("----------------------------");

            // 使用委托

            Func<int, string> fun5 = delegate (int i) { return i.ToString(); };

            string result5 = fun5(5);

            Console.WriteLine($"这里是一个参数一个返回值的委托,返回值是:{result5}");

            Console.WriteLine("----------------------------");

            // 使用匿名委托

            Func<int, string> fun6 = (int i) =>

            {

                return i.ToString();

            };

            string result6 = fun6(6);

            Console.WriteLine($"这里是一个参数一个返回值的匿名委托,返回值是:{result6}");

            Console.WriteLine("----------------------------");

            // 多个输入参数

            Func<int, string, bool> fun7 = new Func<int, string, bool>(FunWithMultiPara);

            bool result7 = fun7(2, "2");

            Console.WriteLine($"这里是有多个输入参数的方法,返回值是:{result7}");

            Console.WriteLine("----------------------------");

            // 使用委托

            Func<int, string, bool> fun8 = delegate (int i, string s)

            {

                return i.ToString().Equals(s) ? true : false;

            };

            bool result8 = fun8(2, "abc");

            Console.WriteLine($"这里是有多个输入参数的委托,返回值是:{result8}");

            Console.WriteLine("----------------------------");

            // 使用匿名委托

            Func<int, string, bool> fun9 = (int i, string s) =>

            {

                return i.ToString().Equals(s) ? true : false;

            };

            bool result9 = fun9(45, "ert");

            Console.WriteLine($"这里是有多个输入参数的匿名委托,返回值是:{result9}");

            Console.ReadKey();

 

        }

 

        static int FunWithNoPara()

        {

            return 10;

        }

 

        static int FunWithPara(int i)

        {

            return i;

        }

 

        static bool FunWithMultiPara(int i,string s)

        {

            return i.ToString().Equals(s) ? true : false;

        }

    }

}

运行结果:

4、真实示例

在下面的示例中,利用Func委托封装数据库通用访问类。

1、定义BaseModel基类

1

2

3

4

5

6

7

8

9

10

11

12

13

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace FunApplication.Model

{

    public class BaseModel

    {

        public int Id { get; set; }

    }

}

2、定义Student类继承自BaseModel基类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace FunApplication.Model

{

    public class Student : BaseModel

    {

        public string Name { get; set; }

 

        public int Age { get; set; }

 

        public int Sex { get; set; }

 

        public string Email { get; set; }

    }

}

3、定义数据库访问方法接口

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

using FunApplication.Model;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace FunApplication.IDAL

{

    public interface IBaseDAL

    {

        T Query<T>(int id) where T : BaseModel;

 

        List<T> QueryAll<T>() where T : BaseModel;

 

        int Insert<T>(T t) where T : BaseModel;

 

        int Update<T>(T t) where T : BaseModel;

 

        int Delete<T>(int id) where T : BaseModel;

    }

}

4、定义属性帮助类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Text;

using System.Threading.Tasks;

 

namespace FunApplication.AttributeExtend

{

    public static class AttributeHelper

    {

        public static string GetColumnName(this PropertyInfo prop)

        {

            if (prop.IsDefined(typeof(ColumnAttribute), true))

            {

                ColumnAttribute attribute = (ColumnAttribute)prop.GetCustomAttribute(typeof(ColumnAttribute), true);

                return attribute.GetColumnName();

            }

            else

            {

                return prop.Name;

            }

        }

    }

}

5、定义ColumnAttribute类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace FunApplication.AttributeExtend

{

    [AttributeUsage(AttributeTargets.Property)]

    public class ColumnAttribute : Attribute

    {

        public ColumnAttribute(string name)

        {

            this._Name = name;

        }

 

        private string _Name = null;

        public string GetColumnName()

        {

            return this._Name;

        }

    }

}

6、定义数据库方法接口实现类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

using FunApplication.IDAL;

using FunApplication.Model;

using System;

using System.Collections.Generic;

using System.Configuration;

using System.Data.SqlClient;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Reflection;

using FunApplication.AttributeExtend;

 

namespace FunApplication.DAL

{

    public  class BaseDAL : IBaseDAL

    {

        // 数据库链接字符串

        private static string strConn = ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString;

        public  int Delete<T>(int id) where T : BaseModel

        {

            int result = 0;

 

            using (SqlConnection conn = new SqlConnection(strConn))

            {

                string strSQL = "delete from Student where Id=@Id";

                SqlParameter para = new SqlParameter("Id", id);

                SqlCommand command = new SqlCommand(strSQL, conn);

                command.Parameters.Add(para);

                conn.Open();

                result = command.ExecuteNonQuery();

            }

            return result;

        }

 

        public int Insert<T>(T t) where T : BaseModel

        {

            int result = 0;

            using (SqlConnection conn = new SqlConnection(strConn))

            {

                Type type = typeof(T);

                var propArray = type.GetProperties().Where(p => p.Name != "Id");

                string strSQL = "insert into Student Values (@Name,@Age,@Sex,@Email) ";

                SqlCommand command = new SqlCommand(strSQL, conn);

                var parameters = propArray.Select(p => new SqlParameter($"@{p.GetColumnName()}", p.GetValue(t) ?? DBNull.Value)).ToArray();

                command.Parameters.AddRange(parameters);

                conn.Open();

                result = command.ExecuteNonQuery();

            }

                return result;

        }

 

        public T Query<T>(int id) where T : BaseModel

        {

            Type type = typeof(T);

            string columnString = string.Join(",", type.GetProperties().Select(p => $"[{p.GetColumnName()}]"));

            string sql = $"SELECT {columnString} FROM [{type.Name}] WHERE Id={id}";

            T t = null;// (T)Activator.CreateInstance(type);

 

            using (SqlConnection conn = new SqlConnection(strConn))

            {

                SqlCommand command = new SqlCommand(sql, conn);

                conn.Open();

                SqlDataReader reader = command.ExecuteReader();

                List<T> list = this.ReaderToList<T>(reader);

                t = list.FirstOrDefault();         

            }

            return t;

        }

 

        public List<T> QueryAll<T>() where T : BaseModel

        {

            Type type = typeof(T);

            string columnString = string.Join(",", type.GetProperties().Select(p => $"[{p.GetColumnName()}]"));

            string sql = $"SELECT {columnString} FROM [{type.Name}] ";

            List<T> list = new List<T>();

            using (SqlConnection conn = new SqlConnection(strConn))

            {

                SqlCommand command = new SqlCommand(sql, conn);

                conn.Open();

                SqlDataReader reader = command.ExecuteReader();

                list = this.ReaderToList<T>(reader);

            }

            return list;

        }

 

        public int Update<T>(T t) where T : BaseModel

        {

            int result = 0;

            using (SqlConnection conn = new SqlConnection(strConn))

            {

                Type type = typeof(T);

                var propArray = type.GetProperties().Where(p => p.Name != "Id");

                string columnString = string.Join(",", propArray.Select(p => $"[{p.GetColumnName()}]=@{p.GetColumnName()}"));

                var parameters = propArray.Select(p => new SqlParameter($"@{p.GetColumnName()}", p.GetValue(t) ?? DBNull.Value)).ToArray();               

                //必须参数化  否则引号?  或者值里面还有引号

                string strSQL = $"UPDATE [{type.Name}] SET {columnString} WHERE Id={t.Id}";

                SqlCommand command = new SqlCommand(strSQL, conn);

                command.Parameters.AddRange(parameters);

                conn.Open();

                result = command.ExecuteNonQuery();           

            }

            return result;

        }

 

        private List<T> ReaderToList<T>(SqlDataReader reader) where T : BaseModel

        {

            Type type = typeof(T);

            List<T> list = new List<T>();

            while (reader.Read())//表示有数据  开始读

            {

                T t = (T)Activator.CreateInstance(type);

                foreach (var prop in type.GetProperties())

                {

                    object oValue = reader[prop.GetColumnName()];

                    if (oValue is DBNull)

                        oValue = null;

                    prop.SetValue(t, oValue);//除了guid和枚举

                }

                list.Add(t);

            }

            return list;

        }

    }

}

7、在Main()方法中调用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

using FunApplication.DAL;

using FunApplication.Model;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace FunApplication

{

    class Program

    {

        static void Main(string[] args)

        {

            #region MyRegion

            BaseDAL dal = new BaseDAL();

            // 查询

            Student student = dal.Query<Student>(2);

            Console.WriteLine($"姓名:{student.Name},年龄:{student.Age},Email地址:{student.Email}");

            Console.WriteLine("----------------------------");

            // 查询所有

            List<Student> list = dal.QueryAll<Student>();

            Console.WriteLine($"集合个数:{list.Count}");

            Console.WriteLine("----------------------------");

            // 插入

            Student studentIns = new Student()

            {

                Name = "小明",

                Age = 20,

                Sex = 2,

                Email = "xiaoming@qq.com"

            };

            bool resultIns = dal.Insert<Student>(studentIns) > 0 ? true : false;

            Console.WriteLine($"插入执行结果:{resultIns}");

            Console.WriteLine("----------------------------");

            // 更新

            Student studentUpd = new Student()

            {

                Id = 1,

                Name = "zhangsan1234",

                Age = 20,

                Sex = 2,

                Email = "zhangsan1234@qq.com"

            };

            bool resultUpd = dal.Update<Student>(studentUpd) > 0 ? true : false;

            Console.WriteLine($"更新执行结果:{resultUpd}");

            Console.WriteLine("----------------------------");

            // 删除

            bool resultDel = dal.Delete<Student>(3) > 0 ? true : false;

            Console.WriteLine($"删除执行结果:{resultDel}");

            #endregion

            Console.ReadKey();

        }

    }

}

8、结果

9、优化

仔细观察上面步骤7中的代码,你会发现在每个方法中都有重复的代码,打开链接,执行SqlCommand命令,那么这些重复的代码能不能提取到一个公共的方法中进行调用呢?答案是可以的,那就是利用Func委托,看下面优化后的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

using FunApplication.AttributeExtend;

using FunApplication.IDAL;

using FunApplication.Model;

using System;

using System.Collections.Generic;

using System.Configuration;

using System.Data;

using System.Data.SqlClient;

using System.Linq;

using System.Reflection;

using System.Text;

using System.Threading.Tasks;

 

namespace FunApplication.DAL

{

    public class FunBaseDAL : IBaseDAL

    {

        // 数据库链接字符串

        private static string strConn = ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString;

 

        public int Delete<T>(int id) where T : BaseModel

        {

            Type type = typeof(T);

            string sql = $"delete from {type.Name} where Id=@Id";

            Func<SqlCommand, int> func = (SqlCommand command) =>

            {              

                SqlParameter para = new SqlParameter("Id", id);

                command.Parameters.Add(para);

                return command.ExecuteNonQuery();

            };

 

            return ExcuteSql<int>(sql, func);

        }

 

        public int Insert<T>(T t) where T : BaseModel

        {

            int result = 0;

            Type type = typeof(T);

            var propArray = type.GetProperties().Where(p => p.Name != "Id");

            string strSQL = "insert into Student Values (@Name,@Age,@Sex,@Email) ";

            var parameters = propArray.Select(p => new SqlParameter($"@{p.GetColumnName()}", p.GetValue(t) ?? DBNull.Value)).ToArray();

            Func<SqlCommand, int> func = (SqlCommand command) =>

            {

                command.Parameters.AddRange(parameters);

                return command.ExecuteNonQuery();

            };

            result = ExcuteSql<int>(strSQL, func);

            return result;

        }

 

        public T Query<T>(int id) where T : BaseModel

        {

            Type type = typeof(T);

            string columnString = string.Join(",", type.GetProperties().Select(p => $"[{p.GetColumnName()}]"));

            string sql = $"SELECT {columnString} FROM [{type.Name}] WHERE Id=@Id";

            T t = null;

            DataTable dt = new DataTable();

             

            Func<SqlCommand, T> func = (SqlCommand command) =>

            {

                SqlParameter para = new SqlParameter("@Id", id);

                command.Parameters.Add(para);

                SqlDataAdapter adapter = new SqlDataAdapter(command);

                //SqlDataReader reader = command.ExecuteReader();

                //List<T> list = this.ReaderToList<T>(reader);

                adapter.Fill(dt);

                List<T> list = ConvertToList<T>(dt);

                T tResult = list.FirstOrDefault();

                return tResult;

            };

            t = ExcuteSql<T>(sql, func);

            return t;

        }

 

        public List<T> QueryAll<T>() where T : BaseModel

        {

            Type type = typeof(T);

            string columnString = string.Join(",", type.GetProperties().Select(p => $"[{p.GetColumnName()}]"));

            string sql = $"SELECT {columnString} FROM [{type.Name}] ";

            T t = null;

 

            Func<SqlCommand, List<T>> func = (SqlCommand command) =>

            {

                SqlDataReader reader = command.ExecuteReader();

                List<T> list = this.ReaderToList<T>(reader);

                return list;

            };

            return ExcuteSql<List<T>>(sql, func);

        }

 

        public int Update<T>(T t) where T : BaseModel

        {

            int result = 0;

            Type type = typeof(T);

            var propArray = type.GetProperties().Where(p => p.Name != "Id");

            string columnString = string.Join(",", propArray.Select(p => $"[{p.GetColumnName()}]=@{p.GetColumnName()}"));

            var parameters = propArray.Select(p => new SqlParameter($"@{p.GetColumnName()}", p.GetValue(t) ?? DBNull.Value)).ToArray();

            //必须参数化  否则引号?  或者值里面还有引号

            string strSQL = $"UPDATE [{type.Name}] SET {columnString} WHERE Id={t.Id}";

            Func<SqlCommand, int> func = (SqlCommand command) =>

            {

                command.Parameters.AddRange(parameters);

                return command.ExecuteNonQuery();

            };

            result = ExcuteSql<int>(strSQL, func);

            return result;

        }

 

 

        //多个方法里面重复对数据库的访问  想通过委托解耦,去掉重复代码

        private T ExcuteSql<T>(string sql, Func<SqlCommand, T> func)

        {

            using (SqlConnection conn = new SqlConnection(strConn))

            {

                using (SqlCommand command = new SqlCommand(sql, conn))

                {

                    conn.Open();

                    SqlTransaction sqlTransaction = conn.BeginTransaction();

                    try

                    {

                        command.Transaction = sqlTransaction;

                        T tResult = func.Invoke(command);

                        sqlTransaction.Commit();

                        return tResult;

                    }

                    catch (Exception ex)

                    {

                        sqlTransaction.Rollback();

                        throw;

                    }

                }

            }

        }

 

        private List<T> ReaderToList<T>(SqlDataReader reader) where T : BaseModel

        {

            Type type = typeof(T);

            List<T> list = new List<T>();

            while (reader.Read())//表示有数据  开始读

            {

                T t = (T)Activator.CreateInstance(type);

                foreach (var prop in type.GetProperties())

                {

                    object oValue = reader[prop.GetColumnName()];

                    if (oValue is DBNull)

                        oValue = null;

                    prop.SetValue(t, oValue);//除了guid和枚举

                }

                list.Add(t);

            }

            reader.Close();

            return list;

        }

    }

}

10、在Main()方法中调用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

using FunApplication.DAL;

using FunApplication.Model;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace FunApplication

{

    class Program

    {

        static void Main(string[] args)

        {

            #region 传统实现

            //BaseDAL dal = new BaseDAL();

            //// 查询

            //Student student = dal.Query<Student>(2);

            //Console.WriteLine($"姓名:{student.Name},年龄:{student.Age},Email地址:{student.Email}");

            //Console.WriteLine("----------------------------");

            //// 查询所有

            //List<Student> list = dal.QueryAll<Student>();

            //Console.WriteLine($"集合个数:{list.Count}");

            //Console.WriteLine("----------------------------");

            //// 插入

            //Student studentIns = new Student()

            //{

            //    Name = "小明",

            //    Age = 20,

            //    Sex = 2,

            //    Email = "xiaoming@qq.com"

            //};

            //bool resultIns = dal.Insert<Student>(studentIns) > 0 ? true : false;

            //Console.WriteLine($"插入执行结果:{resultIns}");

            //Console.WriteLine("----------------------------");

            //// 更新

            //Student studentUpd = new Student()

            //{

            //    Id = 1,

            //    Name = "zhangsan1234",

            //    Age = 20,

            //    Sex = 2,

            //    Email = "zhangsan1234@qq.com"

            //};

            //bool resultUpd = dal.Update<Student>(studentUpd) > 1 ? true : false;

            //Console.WriteLine($"更新执行结果:{resultUpd}");

            //Console.WriteLine("----------------------------");

            //// 删除

            //bool resultDel = dal.Delete<Student>(5) > 1 ? true : false;

            //Console.WriteLine($"删除执行结果:{resultDel}");

            #endregion

 

            #region 利用委托

            // 查询

            FunBaseDAL dal = new FunBaseDAL();

            Student student = dal.Query<Student>(1);

            Console.WriteLine($"姓名:{student.Name},年龄:{student.Age},Email地址:{student.Email}");

            Console.WriteLine("----------------------------");

            // 查询所有

            List<Student> list = dal.QueryAll<Student>();

            Console.WriteLine($"集合个数:{list.Count}");

            Console.WriteLine("----------------------------");

            // 插入

            Student studentIns = new Student()

            {

                Name = "tom",

                Age = 19,

                Sex = 1,

                Email = "tom@163.com"

            };

            bool resultIns = dal.Insert<Student>(studentIns) > 0 ? true : false;

            Console.WriteLine($"插入执行结果:{resultIns}");

            Console.WriteLine("----------------------------");

            List<Student> list1 = dal.QueryAll<Student>();

            Console.WriteLine($"插入后集合个数:{list1.Count}");

            Console.WriteLine("----------------------------");

            // 更新

            Student studentUpd = new Student()

            {

                Id = 2,

                Name = "马六123",

                Age = 20,

                Sex = 2,

                Email = "maliu1234@qq.com"

            };

            bool resultUpd = dal.Update<Student>(studentUpd) > 0 ? true : false;

            Console.WriteLine($"更新执行结果:{resultUpd}");

            Console.WriteLine("----------------------------");

            // 删除

            bool resultDel = dal.Delete<Student>(8) > 0 ? true : false;

            Console.WriteLine($"删除执行结果:{resultDel}");

            List<Student> list2 = dal.QueryAll<Student>();

            Console.WriteLine($"删除后集合个数:{list2.Count}");

            Console.WriteLine("----------------------------");

            #endregion

            Console.ReadKey();

        }

    }

}

11、结果

注意

在使用SqlDataReader的时候有时会报错:“已有打开的与此Command相关联的DataReader,必须先将它关闭”。

同时打开两个或循环多个sqldatareader会出现以上错误。因为用的是sqldatareader做数据库的数据读取,sqlconnection开启没有关闭。

一个SqlConnection只能执行一次事务,没用一次必须关闭然后再开启。上面我只用了一次没有关闭,直接开启所以会报错。解决方案有如下两种:

1、其实不用多次打开在开启,那样实现起来很麻烦。直接在连接字符串的后面加上MultipleActiveResultSets=true即可。 配置文件定义如下:

1

2

3

4

5

6

7

8

9

10

11

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <connectionStrings>

    <!--<add name="DbConnection" connectionString="Server=.;Initial Catalog=MyDb;User ID=sa;Password=123456;MultipleActiveResultSets=True"/>-->

    <!--配置文件里面添加MultipleActiveResultSets=True-->

    <add name="DbConnection" connectionString="Server=.;Initial Catalog=MyDb;User ID=sa;Password=123456;MultipleActiveResultSets=True"/>

  </connectionStrings>

    <startup>

        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />

    </startup>

</configuration>

2、使用DataTable

在上面是使用的SqlDataReader读取数据,然后转换成List<T>,可以用DataTable代替SqlDataReader,这样就不会报错了,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

/// <summary>

/// 将DataTable转换成List

/// </summary>

/// <typeparam name="T"></typeparam>

/// <param name="dt"></param>

/// <returns></returns>

private List<T> ConvertToList<T>(DataTable dt) where T:BaseModel

{

      Type type = typeof(T);

      List<T> list = new List<T>();

      foreach(DataRow dr in dt.Rows)

      {

          T t = (T)Activator.CreateInstance(type);

          foreach(PropertyInfo prop in type.GetProperties())

          {

               object value = dr[prop.GetColumnName()];

               if(value is DBNull)

               {

                    value = null;

               }

               prop.SetValue(t, value);

          }

          list.Add(t);

        }

        return list;

}


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://www.cnblogs.com/dotnet261010/p/10109837.html
相关文章
  • WPF实现窗体亚克力效果的代码

    WPF实现窗体亚克力效果的代码
    WPF 窗体设置亚克力效果 框架使用大于等于.NET40。 Visual Studio 2022。 项目使用MIT开源许可协议。 WindowAcrylicBlur设置亚克力颜色。 Opacity设置透
  • C#非托管泄漏中HEAP_ENTRY的Size对不上解析

    C#非托管泄漏中HEAP_ENTRY的Size对不上解析
    一:背景 1. 讲故事 前段时间有位朋友在分析他的非托管泄漏时,发现NT堆的_HEAP_ENTRY的 Size 和!heap命令中的 Size 对不上,来咨询是怎么回事?
  • C#中ArrayList 类的使用介绍
    一:ArrayList 类简单说明 动态数组ArrayList类在System.Collecions的命名空间下,所以使用时要加入System.Collecions命名空间,而且ArrayList提供添加,
  • C#使用BinaryFormatter类、ISerializable接口、XmlSeriali

    C#使用BinaryFormatter类、ISerializable接口、XmlSeriali
    序列化是将对象转换成字节流的过程,反序列化是把字节流转换成对象的过程。对象一旦被序列化,就可以把对象状态保存到硬盘的某个位
  • C#序列化与反序列化集合对象并进行版本控制
    当涉及到跨进程甚至是跨域传输数据的时候,我们需要把对象序列化和反序列化。 首先可以使用Serializable特性。 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • C#事件中关于sender的用法解读

    C#事件中关于sender的用法解读
    C#事件sender的小用法 开WPF新坑了,看了WPF的炫酷界面,再看看winForm实在是有些惨不忍睹(逃)。后面会开始写一些短的学习笔记。 一、什么
  • 在C#程序中注入恶意DLL的方法

    在C#程序中注入恶意DLL的方法
    一、背景 前段时间在训练营上课的时候就有朋友提到一个问题,为什么 Windbg 附加到 C# 程序后,程序就处于中断状态了?它到底是如何实现
  • 基于C#实现一个简单的FTP操作工具
    实现功能 实现使用FTP上传、下载、重命名、刷新、删除功能 开发环境 开发工具: Visual Studio 2013 .NET Framework版本:4.5 实现代码 1 2 3 4 5 6 7
  • C#仿QQ实现简单的截图功能

    C#仿QQ实现简单的截图功能
    接上一篇写的截取电脑屏幕,我们在原来的基础上加一个选择区域的功能,实现自定义选择截图。 个人比较懒,上一篇的代码就不重新设计
  • C#实现线性查找算法的介绍
    线性查找,肯定是以线性的方式,在集合或数组中查找某个元素。 通过代码来理解线性查找 什么叫线性?还是在代码中体会吧。 首先需要一
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计