近期开发项目中用到的编码小技巧汇总说明

简介:

1.默认EF生成的连接字符串比较的长和怪异,若想使用普通的连接字符串来连接EF,则可以通过创建分部类,并重写一个构造函数,在构造函数中通过动态拼接EntityConnectionString得到EF所需的连接字符串,具代实现代码如下:

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
public  partial  class  DataEntities
{
     private  static  ConcurrentDictionary< string string > entityConnStrings =  new  ConcurrentDictionary< string string >();
 
     public  DataEntities( string  connName)
         base (BuildEntityConnectionString(connName))
     {
 
     }
 
     private  static  string  BuildEntityConnectionString( string  connName)
     {
 
         if  (!entityConnStrings.ContainsKey(connName))
         {
             var  connStrSetting = System.Configuration.ConfigurationManager.ConnectionStrings[connName];
 
             EntityConnectionStringBuilder entityConnStrBuilder =  new  EntityConnectionStringBuilder();
             entityConnStrBuilder.Provider = connStrSetting.ProviderName;
             entityConnStrBuilder.ProviderConnectionString = EncryptUtility.DesDecrypt( "XXXXX" , connStrSetting.ConnectionString);
             entityConnStrBuilder.Metadata =  "res://*/Data.csdl|res://*/Data.ssdl|res://*/Data.msl" ;
             string  entityConnString = entityConnStrBuilder.ToString();
             entityConnStrings.AddOrUpdate(connName, entityConnString, (key, value) => entityConnString);
         }
         return  entityConnStrings[connName];
     }
}

注意上面的类是一个分部类:partial,同时BuildEntityConnectionString方法是一个静态方法,在BuildEntityConnectionString方法中ProviderConnectionString = EncryptUtility.DesDecrypt("XXXXX", connStrSetting.ConnectionString);是关键,我这里是对config中的连接字符串 也都进行了加密,故此处我需要解密,若无这个需求可以直接:ProviderConnectionString =connStrSetting.ConnectionString即可。后续实例化EF上下文对象时,请使用:DataEntities(string connName)这个构造涵数即可,DataEntities是具体的EF上下文对象,大家的EF上下文类名均可能不相同。

2.支持一个通用对象的XML序列化(即:一个类中有可变类型属性成员,需要不同的序列结果及生成不同的序列元素名称),具体实现代码如下:

一个需要被序列化成XML的类:其中要求生成的XML元素detail必需有子元素,且子元素名称及子元素内部属性根据类型的不同而不同(即:detail元素下的子元素是可变的)

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
[XmlRootAttribute( "master" )]
public  class  DemoMaster<T>  where  T :  class
{
     [XmlElement( "attr" )]
     public  string  DemoAttr {  get set ; }
 
     [XmlElement( "detail" )]
     public  DemoDetail<T> DemoDetail {  get set ; }  //关键点在这里,该属性元素为:detail,但其子元素根据T不同而不同
 
}
public  class  DemoDetail<T> : IXmlSerializable  where  T :  class
{
     public  T body {  get set ; }
 
     public  System.Xml.Schema.XmlSchema GetSchema()
     {
         return  null ;
     }
 
     public  void  ReadXml(System.Xml.XmlReader reader)
     {
         string  bodyStr = reader.ReadInnerXml();
         this .body = XmlHelper.XmlDeserialize<T>(bodyStr, Encoding.UTF8);
     }
 
     public  void  WriteXml(System.Xml.XmlWriter writer)
     {
         writer.WriteRaw(XmlHelper.XmlSerialize( this .body, Encoding.UTF8,  true ));
     }
}
 
[XmlTypeAttribute( "list-a" , AnonymousType =  false )]
public  class  DemoDetailA
{
     public  string  Apro1 {  get set ; }
 
     public  string  Apro2 {  get set ; }
 
     public  string  Apro3 {  get set ; }
}
 
[XmlTypeAttribute( "list-b" , AnonymousType =  false )]
public  class  DemoDetailB
{
     public  string  Bpro1 {  get set ; }
 
     public  string  Bpro2 {  get set ; }
 
     public  string  Bpro3 {  get set ; }
}
 
[XmlTypeAttribute( "list-c" , AnonymousType =  false )]
public  class  DemoDetailC
{
     public  string  Cpro1 {  get set ; }
 
     public  string  Cpro2 {  get set ; }
 
     public  string  Cpro3 {  get set ; }
}

注意上面代码中,需要关注:DemoDetail属性及DemoDetail<T>类,DemoDetail属性仅是为了生成detail元素节点,而子节点则由DemoDetail<T>类来进行生成,DemoDetail<T>是实现了IXmlSerializable接口,在XML序列化时,DemoDetail<T>类仅将body属性对应的T类型实例内容进行序列化(WriteRaw),而反序列化时,则先反序列化body属性对应的T类型实例,然后赋值给body属性,这也是巧妙之处,DemoDetail<T>类本身并没有真正参与到序列化中,故序列化的字符串也看不到DemoDetail<T>类相关的元素,DemoDetail<T>类仅仅是一个XML序列化格式生成的中介。序列化的XML结果如下:

序列化代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var  demo1 =  new  DemoMaster<DemoDetailA>()
{
     DemoAttr =  "demo1" ,
     DemoDetail =  new  DemoDetail<DemoDetailA>() { body =  new  DemoDetailA() { Apro1 =  "demoA1" , Apro2 =  "demoA2" , Apro3 =  "demoA3"  } }
};
 
var  demo2 =  new  DemoMaster<DemoDetailB>()
{
     DemoAttr =  "demo2" ,
     DemoDetail =  new  DemoDetail<DemoDetailB>() { body =  new  DemoDetailB() { Bpro1 =  "demoB1" , Bpro2 =  "demoB2" , Bpro3 =  "demoB3"  } }
};
 
var  demo3 =  new  DemoMaster<DemoDetailC>()
{
     DemoAttr =  "demo3" ,
     DemoDetail =  new  DemoDetail<DemoDetailC>() { body =  new  DemoDetailC() { Cpro1 =  "demoC1" , Cpro2 =  "demoC2" , Cpro3 =  "demoC3"  } }
};
 
textBox1.Text = XmlHelper.XmlSerialize(demo1, Encoding.UTF8);
 
textBox1.Text +=  "\r\n"  + XmlHelper.XmlSerialize(demo2, Encoding.UTF8);
 
textBox1.Text +=  "\r\n"  + XmlHelper.XmlSerialize(demo3, Encoding.UTF8);

序列化的XML:

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
<? xml  version="1.0" encoding="utf-8"?>
< master >
     < attr >demo1</ attr >
     < detail >< list-a >
     < Apro1 >demoA1</ Apro1 >
     < Apro2 >demoA2</ Apro2 >
     < Apro3 >demoA3</ Apro3 >
</ list-a ></ detail >
</ master >
 
<? xml  version="1.0" encoding="utf-8"?>
< master >
     < attr >demo2</ attr >
     < detail >< list-b >
     < Bpro1 >demoB1</ Bpro1 >
     < Bpro2 >demoB2</ Bpro2 >
     < Bpro3 >demoB3</ Bpro3 >
</ list-b ></ detail >
</ master >
 
<? xml  version="1.0" encoding="utf-8"?>
< master >
     < attr >demo3</ attr >
     < detail >< list-c >
     < Cpro1 >demoC1</ Cpro1 >
     < Cpro2 >demoC2</ Cpro2 >
     < Cpro3 >demoC3</ Cpro3 >
</ list-c ></ detail >
</ master >

3.winform DataGridView 实现指定列采取密码框模式显示与编辑,以及列绑定到复合属性(即:绑定到多层次属性),具体实现代码如下:

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
             dataGridView1.CellFormatting +=  new  DataGridViewCellFormattingEventHandler(dataGridView1_CellFormatting);
             dataGridView1.EditingControlShowing +=  new  DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
 
 
         public  string  EvaluateValue( object  obj,  string  property)
         {
             string  retValue =  string .Empty;
             string [] names = property.Split( '.' );
 
             for  ( int  i = 0; i < names.Count(); i++)
             {
                 try
                 {
                     var  prop = obj.GetType().GetProperty(names[i]);
                     var  result = prop.GetValue(obj,  null );
                     if  (result !=  null )
                     {
                         obj = result;
                         retValue = result.ToString();
                     }
                     else
                     {
                         break ;
                     }
                 }
                 catch  (Exception)
                 {
                     throw ;
                 }
             }
 
             return  retValue;
         }
 
 
         private  void  dataGridView1_CellFormatting( object  sender, DataGridViewCellFormattingEventArgs e)
         {
 
             if  (dataGridView1.Columns[e.ColumnIndex].DataPropertyName.Contains( "." ))
             {
                 e.Value = EvaluateValue(dataGridView1.Rows[e.RowIndex].DataBoundItem, dataGridView1.Columns[e.ColumnIndex].DataPropertyName);
             }
 
 
             if  (dataGridView1.Columns[e.ColumnIndex].Name ==  "KeyCode" )
             {
                 if  (e.Value !=  null  && e.Value.ToString().Length > 0)
                 {
                     e.Value =  new  string ( '*' , e.Value.ToString().Length);
                 }
             }
         }
 
         private  void  dataGridView1_EditingControlShowing( object  sender, DataGridViewEditingControlShowingEventArgs e)
         {
             int  i =  this .dataGridView1.CurrentCell.ColumnIndex;
             bool  usePassword =  false ;
             if  (dataGridView1.Columns[i].Name ==  "KeyCode" )
             {
                 usePassword =  true ;
             }
             TextBox txt = e.Control  as  TextBox;
             if  (txt !=  null )
             {
                 txt.UseSystemPasswordChar = usePassword;
             }
         }
 
//示例:绑定的源数据类定义
     public  class  DemoBindClass
     {
         public  string  Attr {  get set ; }
 
         public  string  KeyCode {  get set ; }
 
         public  DemoDetailA Detail {  get set ; }
     }
 
 
     public  class  DemoDetailA
     {
         public  string  Apro1 {  get set ; }
 
         public  string  Apro2 {  get set ; }
 
         public  string  Apro3 {  get set ; }
 
         public  DemoDetailB DetailChild {  get set ; }
     }
 
 
     public  class  DemoDetailB
     {
         public  string  Bpro1 {  get set ; }
 
         public  string  Bpro2 {  get set ; }
 
         public  string  Bpro3 {  get set ; }
     }

绑定到数据源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var  demo =  new [] {
     new  DemoBindClass()
         {
             Attr =  "demo" ,
             KeyCode= "a123456789b" ,
             Detail =