DbContext_Test.cs 6.3 KB

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