EntityLoader_CustomLoader_Test.cs 6.4 KB

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