前言
看了大家都在造轮子,我也要写一个站点自用了,没有数据库怎么办,又不想用Sqlite,所以自己造吧。大不了就是都文件到内存,然后内存到文件。正文对于这种操作,无非就是反射c#教程一下属性,然后通过对象和属性进行更新。当然EF也有这样的功能,不过对Model而言太臃肿了,这里就不用了。上代码
1 /// <summary>
2 /// 文件系统数据库
3 /// 主键Attribute [Key],支持主键比较
4 /// </summary>
5 /// <typeparam name="T"></typeparam>
6 public class FileDbHelper<T> where T : class
7 {
8 private static List<T> dataList = new List<T>();
9 private static string savePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", typeof(T).Name + ".mydb");
10 private static JavaScriptSerializer js = new JavaScriptSerializer();
11
12 static FileDbHelper()
13 {
14 string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data");
15 if (!Directory.Exists(dir))
16 {
17 Directory.CreateDirectory(dir);
18 }
19
20 string savePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", typeof(T).Name + ".mydb");
21 if (File.Exists(savePath))
22 {
23 string[] lines = File.ReadAllLines(savePath, Encoding.UTF8);
24 foreach (var line in lines)
25 {
26 if (!string.IsNullOrEmpty(line))
27 {
28 try
29 {
30 dataList.Add(js.Deserialize<T>(line));
31 }
32 catch { }
33 }
34 }
35 }
36 }
37
38 public static void Add(T model)
39 {
40 lock (dataList)
41 {
42 dataList.Add(model);
43 SaveFile();
44 }
45 }
46
47 public static void AddList(List<T> list)
48 {
49 lock (dataList)
50 {
51 dataList.AddRange(list);
52 SaveFile();
53 }
54 }
55
56 public static void AddOrUpdate(T model, params string[] args)
57 {
58 lock (dataList)
59 {
60 List<FileDbInfo> infoList = FindKeyDbList(model);
61 T equalModel = CheckKeyEqual(model, infoList);
62 if (equalModel == null)
63 {
64 Add(model);
65 }
66 else
67 {
68 Update(equalModel, model, args);
69 }
70
71 SaveFile();
72 }
73 }
74
75 public static T QueryInfo(T model, params string[] args)
76 {
77 lock (dataList)
78 {
79 List<FileDbInfo> infoList = FindArgsDbList(model, args);
80 T equalModel = CheckKeyEqual(model, infoList, args);
81
82 return equalModel;
83 }
84 }
85
86 public static List<T> QueryList(int page, int pageSize, T model, params string[] args)
87 {
88 lock (dataList)
89 {
90 List<FileDbInfo> infoList = FindArgsDbList(model, args);
91 List<T> equalList = CheckArgsEqualList(model, infoList, args);
92
93 return equalList.Skip(pageSize * (page - 1)).Take(pageSize).ToList();
94 }
95 }
96
97 private static void Update(T oldModel, T newModel, string[] args)
98 {
99 List<string> keyList = ReadKeyName();
100 foreach (PropertyInfo pInfo in newModel.GetType().GetProperties())
101 {
102 if (args.Length > 0)
103 {
104 if (!args.ToList().Contains(pInfo.Name))
105 {
106 Object new_value = pInfo.GetValue(newModel, null);
107 pInfo.SetValue(oldModel, new_value, null);
108 }
109 }
110 else
111 {
112 if (!keyList.Contains(pInfo.Name))
113 {
114 Object new_value = pInfo.GetValue(newModel, null);
115 pInfo.SetValue(oldModel, new_value, null);
116 }
117 }
118 }
119 }
120
121 private static T CheckKeyEqual(T model, List<FileDbInfo> infoList, string[] args = null)
122 {
123 foreach (var item in dataList)
124 {
125 bool is_equal = true;
126 foreach (var info in infoList)
127 {
128 if (args == null || (args != null && args.ToList().Contains(info.key)))
129 {
130 if (ReadString(model, info.key) != ReadString(item, info.key))
131 {
132 is_equal = false;
133 break;
134 }
135 }
136 }
137
138 if (is_equal)
139 {
140 return item;
141 }
142 }
143
144 return null;
145 }
146
147 private static List<T> CheckArgsEqualList(T model, List<FileDbInfo> infoList, string[] args = null)
148 {
149 List<T> result = new List<T>();
150 foreach (var item in dataList)
151 {
152 bool is_equal = true;
153 foreach (var info in infoList)
154 {
155 if (args == null || (args != null && args.ToList().Contains(info.key)))
156 {
157 if (ReadString(model, info.key) != ReadString(item, info.key))
158 {
159 is_equal = false;
160 break;
161 }
162 }
163 }
164
165 if (is_equal)
166 {
167 result.Add(item);
168 }
169 }
170
171 return result;
172 }
173
174 private static List<FileDbInfo> FindKeyDbList(T model, params string[] args)
175 {
176 List<string> keyList = ReadKeyName();
177 var infoList = new List<FileDbInfo>();
178 foreach (var key in keyList)
179 {
180 if (args == null || (args != null && args.ToList().Contains(key)))
181 {
182 infoList.Add(new FileDbInfo(key, ReadString(model, key)));
183 }
184 }
185
186 return infoList;
187 }
188
189 private static List<FileDbInfo> FindArgsDbList(T model, params string[] args)
190 {
191 List<string> keyList = ReadArgsName();
192 var infoList = new List<FileDbInfo>();
193 foreach (var key in keyList)
194 {
195 if (args == null || (args != null && args.ToList().Contains(key)))
196 {
197 infoList.Add(new FileDbInfo(key, ReadString(model, key)));
198 }
199 }
200
201 return infoList;
202 }
203
204 private static List<string> ReadKeyName()
205 {
206 List<string> keyList = new List<string>();
207 foreach (var pInfo in typeof(T).GetProperties())
208 {
209 foreach (var attr in pInfo.GetCustomAttributes(false))
210 {
211 if (attr.GetType() == typeof(KeyAttribute))
212 {
213 keyList.Add(pInfo.Name);
214 }
215 }
216 }
217
218 if (keyList.Count == 0)
219 {
220 throw new Exception("未定义主键,通过设置注解来添加主键[Key],目前只支持int和string");
221 }
222
223 return keyList;
224 }
225
226 private static List<string> ReadArgsName()
227 {
228 List<string> keyList = new List<string>();
229 foreach (var pInfo in typeof(T).GetProperties())
230 {
231 keyList.Add(pInfo.Name);
232 }
233
234 return keyList;
235 }
236
237 private static string ReadString(T model, string key_name)
238 {
239 PropertyInfo propertyInfo = model.GetType().GetProperty(key_name);
240 object obj = propertyInfo.GetValue(model, null);
241 if (propertyInfo.PropertyType == typeof(int))
242 {
243 return obj.ToString();
244 }
245 else if (propertyInfo.PropertyType == typeof(string))
246 {
247 return obj.ToString();
248 }
249 else
250 {
251 return obj.ToString();
252 }
253 }
254
255 private static void SaveFile()
256 {
257 StringBuilder content = new StringBuilder();
258 foreach (var item in dataList)
259 {
260 content.AppendLine(js.Serialize(item));
261 }
262
263 File.WriteAllText(savePath, content.ToString(), new UTF8Encoding(false));
264 }
265 }
266
267 public class FileDbInfo
268 {
269 public FileDbInfo(string key, string str_value)
270 {
271 this.key = key;
272 this.str_value = str_value;
273 }
274
275 public string key { get; set; }
276
277 public string str_value { get; set; }
278 }
279
280 public class KeyAttribute : Attribute { }
281 }
复制代码
使用方式。
复制代码
public class UserInfo2
{
[Key]
public string name { get; set; }
public string pwd { get; set; }
public int age { get; set; }
public string info { get; set; }
}
复制代码
复制代码
// 新增数据
FileDbHelper<UserInfo2>.AddOrUpdate(new UserInfo2() { name = "test1", pwd = "12341", age = 10 });
FileDbHelper<UserInfo2>.AddOrUpdate(new UserInfo2() { name = "test2", pwd = "12342", age = 10 });
FileDbHelper<UserInfo2>.AddOrUpdate(new UserInfo2() { name = "test3", pwd = "12343", age = 11 });
FileDbHelper<UserInfo2>.AddOrUpdate(new UserInfo2() { name = "test4", pwd = "12344", age = 12 });
FileDbHelper<UserInfo2>.AddOrUpdate(new UserInfo2() { name = "test5", pwd = "12345", age = 10 });
// 查询集合,条件查询
var list = FileDbHelper<UserInfo2>.QueryList(1, 10, new UserInfo2() { age = 10 }, "age");
// 单个对象,条件查询
var model = FileDbHelper<UserInfo2>.QueryInfo(new UserInfo2() { age = 12 }, "age");
// 修改所有值
model.info = "hehe";
FileDbHelper<UserInfo2>.AddOrUpdate(model);
// 修改指定的值
FileDbHelper<UserInfo2>.AddOrUpdate(new UserInfo2() { name = "test1", age = 12 }, "age");
var model2 = FileDbHelper<UserInfo2>.QueryInfo(model);
总结:伟大出自平凡。