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 =
|