DbContext_Test.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System.Reflection;
  2. using Microsoft.VisualStudio.TestTools.UnitTesting;
  3. using Vitorm.Entity;
  4. using Vitorm.Entity.DataAnnotations;
  5. using Vitorm.Entity.Loader;
  6. using Vitorm.Entity.LoaderAttribute;
  7. namespace Vitorm.MsTest.CommonTest
  8. {
  9. [TestClass]
  10. public class DbContext_Test
  11. {
  12. [TestMethod]
  13. public void EntityDescriptor_Test()
  14. {
  15. using var dbContext = DataSource.CreateDbContext();
  16. var entityDescriptor = dbContext.GetEntityDescriptor(typeof(User));
  17. var key = entityDescriptor.key;
  18. Assert.AreEqual("userId", key.columnName);
  19. }
  20. [TestMethod]
  21. public void EntityLoader_Test()
  22. {
  23. using var dbContext = DataSource.CreateDbContext();
  24. // #1 EntityLoaderAttribute
  25. {
  26. var users = dbContext.Query<CustomUser2>().Where(m => m.name == "u146").ToList();
  27. var sql = dbContext.Query<CustomUser2>().Where(m => m.name == "u146").ToExecuteString();
  28. Assert.AreEqual(1, users.Count());
  29. Assert.AreEqual(1, users[0].id);
  30. }
  31. // #2 defaultEntityLoader
  32. {
  33. DbContext.defaultEntityLoader.loaders.Insert(0, new CustomEntityLoader());
  34. var users = dbContext.Query<CustomUser>().Where(m => m.name == "u146").ToList();
  35. Assert.AreEqual(1, users.Count());
  36. Assert.AreEqual(1, users[0].id);
  37. }
  38. }
  39. #region Custom Entity
  40. [EntityLoader(Loader = typeof(CustomEntityLoader))]
  41. public class CustomUser2 : CustomUser
  42. {
  43. }
  44. [Property(name = "TableName", value = "User")]
  45. [Property(name = "Schema", value = "dbo")]
  46. public class CustomUser
  47. {
  48. [Label("Key")]
  49. [Label("Identity")]
  50. [Property(name = "ColumnName", value = "userId")]
  51. public int id { get; set; }
  52. [Property(name = "ColumnName", value = "userName")]
  53. [Property(name = "TypeName", value = "varchar(1000)")]
  54. [Label("Required")]
  55. public string name { get; set; }
  56. [Property(name = "ColumnName", value = "userBirth")]
  57. public DateTime? birth { get; set; }
  58. [Property(name = "ColumnName", value = "userFatherId")]
  59. public int? fatherId { get; set; }
  60. [Property(name = "ColumnName", value = "userMotherId")]
  61. public int? motherId { get; set; }
  62. [Label("NotMapped")]
  63. public string test { get; set; }
  64. public static CustomUser NewUser(int id, bool forAdd = false) => new CustomUser { id = id, name = "testUser" + id };
  65. }
  66. #endregion
  67. #region Custom EntityLoader Attribute
  68. [System.AttributeUsage(System.AttributeTargets.All, Inherited = true, AllowMultiple = true)]
  69. public class LabelAttribute : Attribute
  70. {
  71. public LabelAttribute(string label) { this.label = label; }
  72. public string label { get; init; }
  73. }
  74. [System.AttributeUsage(System.AttributeTargets.All, Inherited = true, AllowMultiple = true)]
  75. public class PropertyAttribute : Attribute
  76. {
  77. public string name { get; set; }
  78. public string value { get; set; }
  79. }
  80. #endregion
  81. #region #region Custom EntityLoader
  82. public class CustomEntityLoader : IEntityLoader
  83. {
  84. public void CleanCache() { }
  85. public IEntityDescriptor LoadDescriptor(Type entityType) => LoadFromType(entityType);
  86. public static bool GetTableName(Type entityType, out string tableName, out string schema)
  87. {
  88. var properties = entityType?.GetCustomAttributes<PropertyAttribute>();
  89. tableName = properties?.FirstOrDefault(attr => attr.name == "TableName")?.value;
  90. schema = properties?.FirstOrDefault(attr => attr.name == "Schema")?.value;
  91. return tableName != null;
  92. }
  93. public static EntityDescriptor LoadFromType(Type entityType)
  94. {
  95. if (!GetTableName(entityType, out var tableName, out var schema)) return null;
  96. IColumnDescriptor[] allColumns = entityType?.GetProperties(BindingFlags.Public | BindingFlags.Instance)
  97. .Select(propertyInfo =>
  98. {
  99. var labels = propertyInfo?.GetCustomAttributes<LabelAttribute>();
  100. var properties = propertyInfo?.GetCustomAttributes<PropertyAttribute>();
  101. if (labels.Any(m => m.label == "NotMapped")) return null;
  102. // #1 isKey
  103. bool isKey = labels.Any(m => m.label == "Key");
  104. // #2 column name and type
  105. var columnName = properties.FirstOrDefault(attr => attr.name == "ColumnName")?.value ?? propertyInfo.Name;
  106. var databaseType = properties.FirstOrDefault(attr => attr.name == "TypeName")?.value;
  107. int? columnOrder = int.TryParse(properties.FirstOrDefault(attr => attr.name == "ColumnOrder")?.value, out var order) ? order : null;
  108. // #3 isIdentity
  109. var isIdentity = labels.Any(m => m.label == "Identity");
  110. // #4 isNullable
  111. bool isNullable;
  112. if (labels.Any(m => m.label == "Required")) isNullable = false;
  113. else
  114. {
  115. var type = propertyInfo.PropertyType;
  116. if (type == typeof(string)) isNullable = true;
  117. else
  118. {
  119. isNullable = (type.IsGenericType && typeof(Nullable<>) == type.GetGenericTypeDefinition());
  120. }
  121. }
  122. return new ColumnDescriptor(propertyInfo, columnName: columnName, isKey: isKey, isIdentity: isIdentity, databaseType: databaseType, isNullable: isNullable, columnOrder: columnOrder);
  123. }).Where(column => column != null).ToArray();
  124. return new EntityDescriptor(entityType, allColumns, tableName, schema);
  125. }
  126. }
  127. #endregion
  128. }
  129. }