EntityLoader_CustomLoader_Test.cs 6.7 KB

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