Db4o的第三扩展库的使用
最早的时候只是看过Db4o的一些基本内容,感觉他的理念和使用方法真是太符合我的要求了,但最近在使用Db4o的时候发现,Db4o还是有很多不足之处的。在之前的文章DB4O在进行更新时只能在同一个session中的问题及改进方法中也提到了一些,自己也为改进这些不足作出了自己的尝试。
但在上文的结尾处自己也说了,自己的改进有很多的不足之处,当然上面的文章也没有过多的说这些东西,在这里我详细说一下:
1、数据库本身就是一个非常复杂的系统,在Db4o里面,什么级联更新,更新深度等也都有定义,自己的写的函数在不完整的情况下很有可能会破坏这个系统。
2、数据库往往为了提高效率,作了非常多的优化,在进行数据库扩展的时候肯定会降低其效率。
所以,如果在使用数据库时对以上两点有特别的要求,最好不要使用扩展,无论什么扩展都在有得有失。而且通过这两天的思考,觉得自己写的类也是只能自己使用,别人使用的时候可能就会遇到意想不到的问题。当然,下一步自己会整理一下自己的那个类,分享给大家,但也会和大家说明在什么情况下用会比较好。
相比较我这个业余选手,Db4o也有几个其他人写的相对较为专业一点的类库,介绍给大家:
这个增加了一些Db4o不具有的一些关系数据库的特征,有时真的是很方便的,例如:唯一约束(看到很多介绍说Db4o本身就有这个功能,但一直找不到)、一致性检查、复合主键等功能,而且他的使用也非常的方便:
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 |
namespace Example { class Program { readonly static string databaseFileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "example.db4o"); static void Main(string[] args) { File.Delete(databaseFileName); IEmbeddedConfiguration cfg = Db4oEmbedded.NewConfiguration(); cfg.Common.Add(new TransparentPersistenceSupport(new DeactivatingRollbackStrategy())); cfg.UseExtensions(Assembly.GetAssembly(typeof(Company))); using (IObjectContainer db = Db4oEmbedded.OpenFile(cfg, databaseFileName)) { db.UseExtensions(); Company company = new Company { Id = 1, Name = "Apple, Inc." }; db.Store(company); // exception will be thrown on COMMIT, because the same company name is used //db.Store(new Company { Id = 2, Name = "Apple, Inc." }); Company company2 = new Company { Id = 2, Name = "Google, Inc." }; db.Store(company2); db.Commit(); Department[] depts = new Department[] { new Department { Company = company, Name = "Sales" }, new Department { Company = company, Name = "Support" }, new Department { Company = company2, Name = "Sales" }}; db.Store(depts); // exception will be thrown on COMMIT, because department with this name has already been created in Apple, Inc. //db.Store(new Department { Company = company, Name = "Sales" }); db.Commit(); Employee emp = new Employee { Department = depts[0], Id = 1, FirstName = "John", LastName = "Doe" }; db.Store(emp); // exception will be thrown on COMMIT into db // because employee with this full name already exists independently of company and department //db.Store(new Employee { Department = depts[2], Id = 2, FirstName = "John", LastName = "Doe" }); db.Commit(); // DEFERRED DELETION DEMONSTRATION // mark companies for deletion company.Delete(); company2.Delete(); // mark for deletion all dependent objects (departments in out case) that have cascade deletion behavior db.DeleteCascadeAll(); // make real deletions db.Purge(); // RESULT: // company2 and all its departments will be deleted // company will NOT be deleted because it has a department with an employee which cascade deletion is prohibited // Support department of company will be deleted because it is empty } } [TransparentPersisted] public class Company : Db4oTPEntity { // single field key [Unique] private int _id; // alternative single field key [Unique] private string _name; private string _fullName; private string _address; private string _email; private string _phone, _fax; // only positive values allowed [Range(1, int.MaxValue)] public int Id { get { return _id; } set { _id = value; } } // required property [Required] public string Name { get { return _name; } set { _name = value; } } public string FullName { get { return _fullName; } set { _fullName = value; } } public string Address { get { return _address; } set { _address = value; } } public string Email { get { return _email; } set { _email = value; } } public string Phone { get { return _phone; } set { _phone = value; } } public string Fax { get { return _fax; } set { _fax = value; } } public override string ToString() { return String.Format("({0}) {1}", Id, Name); } public static implicit operator string(Company company) { return company.ToString(); } } [TransparentPersisted] public class Department : Db4oTPEntity { // composite key (_company, _name) // also deletion of a company leads to cascade deletion of all its departments [UniqueGroup(1), DeleteStrategy(DeleteBehavior.Cascade)] private Company _company; [UniqueGroup(1)] private string _name; private string _fullName; private int _sortMetric; // required property [Required] public Company Company { get { return _company; } set { _company = value; } } // required property [Required] public string Name { get { return _name; } set { _name = value; } } public string FullName { get { return _fullName; } set { _fullName = value; } } public int SortMetric { get { return _sortMetric; } set { _sortMetric = value; } } public override string ToString() { return String.Format("({0}) {1}", Company.Id, Name); } public static implicit operator string(Department dept) { return dept.ToString(); } } [TransparentPersisted] public class Employee : Db4oTPEntity { // composite key (_company, _id) [UniqueGroup(1)] private Company _company; [UniqueGroup(1)] private int _id; // alternative key (_firstName, _middleName, _lastNamem, _dateOfBirth) [UniqueGroup(2)] private string _firstName, _middleName, _lastName; [UniqueGroup(2)] private DateTime _dateOfBirth; // prevent deletion of a deparment that has employees // DeleteStrategy(DeleteBehavior.Restrict) can be omitted, because it is default behavior [Indexed, DeleteStrategy(DeleteBehavior.Restrict)] private Department _department; public Company Company { get { return _company; } } [Range(1, int.MaxValue)] public int Id { get { return _id; } set { _id = value; } } [Required] public string FirstName { get { return _firstName; } set { _firstName = value; } } public string MiddleName { get { return _middleName; } set { _middleName = value; } } [Required] public string LastName { get { return _lastName; } set { _lastName = value; } } public string FullName { get { return String.Format("{0} {1} {2}", LastName, FirstName, MiddleName); } } public DateTime DateOfBirth { get { return _dateOfBirth; } set { _dateOfBirth = value; } } [Required] public Department Department { get { return _department; } set { _department = value; _company = value.Company; } } public override string ToString() { return String.Format("({0}/{1}) {2}", Company.Id, Id, FullName); } public static implicit operator string(Employee emp) { return emp.ToString(); } } } } |
这个是官方给的一个例子,感觉是非常有用的,很好的解决了以上几个问题。具体的更多的细节我以后也会分享给大家,这里就不多说了。
这个类库对我来说可能用处并不大,但对大家可能有用,也分享给大家:
他主要有三个功能:1、ASP.NET支持。2、关系数据库映射。3、设置生成。
说点什么