using ZB.MOM.WW.CBDD.Bson; using ZB.MOM.WW.CBDD.Core.Collections; using ZB.MOM.WW.CBDD.Core.Metadata; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ZB.MOM.WW.CBDD.Shared { // --- Basic Entities --- public class User { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = ""; /// /// Gets or sets the age. /// public int Age { get; set; } } // --- Complex Entities (Nested) --- public class ComplexUser { /// /// Gets or sets the id. /// [BsonId] public ObjectId Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = ""; // Direct nested object /// /// Gets or sets the main address. /// public Address MainAddress { get; set; } = new(); // Collection of nested objects /// /// Gets or sets the other addresses. /// public List
OtherAddresses { get; set; } = new(); // Primitive collection /// /// Gets or sets the tags. /// public List Tags { get; set; } = new(); /// /// Gets or sets the secret. /// [BsonIgnore] public string Secret { get; set; } = ""; } public class Address { /// /// Gets or sets the street. /// public string Street { get; set; } = ""; /// /// Gets or sets the city. /// public City City { get; set; } = new(); // Depth 2 } public class City { /// /// Gets or sets the name. /// public string Name { get; set; } = ""; /// /// Gets or sets the zip code. /// public string ZipCode { get; set; } = ""; } // --- Primary Key Test Entities --- public class IntEntity { /// /// Gets or sets the id. /// public int Id { get; set; } /// /// Gets or sets the name. /// public string? Name { get; set; } } public class StringEntity { /// /// Gets or sets the id. /// public required string Id { get; set; } /// /// Gets or sets the value. /// public string? Value { get; set; } } public class GuidEntity { /// /// Gets or sets the id. /// public Guid Id { get; set; } /// /// Gets or sets the name. /// public string? Name { get; set; } } /// /// Entity with string key NOT named "Id" - tests custom key name support /// public class CustomKeyEntity { /// /// Gets or sets the code. /// [System.ComponentModel.DataAnnotations.Key] public required string Code { get; set; } /// /// Gets or sets the description. /// public string? Description { get; set; } } // --- Multi-collection / Auto-init entities --- public class AutoInitEntity { /// /// Gets or sets the id. /// public int Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; } public class Person { /// /// Gets or sets the id. /// public int Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = ""; /// /// Gets or sets the age. /// public int Age { get; set; } } public class Product { /// /// Gets or sets the id. /// public int Id { get; set; } /// /// Gets or sets the title. /// public string Title { get; set; } = ""; /// /// Gets or sets the price. /// public decimal Price { get; set; } } public class AsyncDoc { /// /// Gets or sets the id. /// public int Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = ""; } public class SchemaUser { /// /// Gets or sets the id. /// public int Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = ""; /// /// Gets or sets the address. /// public Address Address { get; set; } = new(); } public class VectorEntity { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the title. /// public string Title { get; set; } = ""; /// /// Gets or sets the embedding. /// public float[] Embedding { get; set; } = Array.Empty(); } public class GeoEntity { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = ""; /// /// Gets or sets the location. /// public (double Latitude, double Longitude) Location { get; set; } } public record OrderId(string Value) { /// /// Initializes a new instance. /// public OrderId() : this(string.Empty) { } } public class OrderIdConverter : ValueConverter { /// public override string ConvertToProvider(OrderId model) => model?.Value ?? string.Empty; /// public override OrderId ConvertFromProvider(string provider) => new OrderId(provider); } public class Order { /// /// Gets or sets the id. /// public OrderId Id { get; set; } = null!; /// /// Gets or sets the customer name. /// public string CustomerName { get; set; } = ""; } public class TestDocument { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the category. /// public string Category { get; set; } = string.Empty; /// /// Gets or sets the amount. /// public int Amount { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; } public class OrderDocument { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the item name. /// public string ItemName { get; set; } = string.Empty; /// /// Gets or sets the quantity. /// public int Quantity { get; set; } } public class OrderItem { /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; /// /// Gets or sets the price. /// public int Price { get; set; } } public class ComplexDocument { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the title. /// public string Title { get; set; } = string.Empty; /// /// Gets or sets the shipping address. /// public Address ShippingAddress { get; set; } = new(); /// /// Gets or sets the items. /// public List Items { get; set; } = new(); } [Table("custom_users", Schema = "test")] public class AnnotatedUser { /// /// Gets or sets the id. /// [Key] public ObjectId Id { get; set; } /// /// Gets or sets the name. /// [Required] [Column("display_name")] [StringLength(50, MinimumLength = 3)] public string Name { get; set; } = ""; /// /// Gets or sets the age. /// [Range(0, 150)] public int Age { get; set; } /// /// Gets the computed info. /// [NotMapped] public string ComputedInfo => $"{Name} ({Age})"; /// /// Gets or sets the location. /// [Column(TypeName = "geopoint")] public (double Lat, double Lon) Location { get; set; } } public class PersonV2 { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; /// /// Gets or sets the age. /// public int Age { get; set; } } /// /// Entity used to test DbContext inheritance /// public class ExtendedEntity { /// /// Gets or sets the id. /// public int Id { get; set; } /// /// Gets or sets the description. /// public string Description { get; set; } = string.Empty; /// /// Gets or sets the created at. /// public DateTime CreatedAt { get; set; } } // ===== SOURCE GENERATOR FEATURE TESTS ===== /// /// Base entity with Id property - test inheritance /// public class BaseEntityWithId { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the created at. /// public DateTime CreatedAt { get; set; } } /// /// Derived entity that inherits Id from base class /// public class DerivedEntity : BaseEntityWithId { /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; /// /// Gets or sets the description. /// public string Description { get; set; } = string.Empty; } /// /// Entity with computed getter-only properties (should be excluded from serialization) /// public class EntityWithComputedProperties { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the first name. /// public string FirstName { get; set; } = string.Empty; /// /// Gets or sets the last name. /// public string LastName { get; set; } = string.Empty; /// /// Gets or sets the birth year. /// public int BirthYear { get; set; } // Computed properties - should NOT be serialized /// /// Gets the full name. /// public string FullName => $"{FirstName} {LastName}"; /// /// Gets the age. /// public int Age => DateTime.Now.Year - BirthYear; /// /// Gets the display info. /// public string DisplayInfo => $"{FullName} (Age: {Age})"; } /// /// Entity with advanced collection types (HashSet, ISet, LinkedList, etc.) /// public class EntityWithAdvancedCollections { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; // Various collection types that should all be recognized /// /// Gets or sets the tags. /// public HashSet Tags { get; set; } = new(); /// /// Gets or sets the numbers. /// public ISet Numbers { get; set; } = new HashSet(); /// /// Gets or sets the history. /// public LinkedList History { get; set; } = new(); /// /// Gets or sets the pending items. /// public Queue PendingItems { get; set; } = new(); /// /// Gets or sets the undo stack. /// public Stack UndoStack { get; set; } = new(); // Nested objects in collections /// /// Gets or sets the addresses. /// public HashSet
Addresses { get; set; } = new(); /// /// Gets or sets the favorite cities. /// public ISet FavoriteCities { get; set; } = new HashSet(); } /// /// Entity with private setters (requires reflection-based deserialization) /// public class EntityWithPrivateSetters { /// /// Gets or sets the id. /// public ObjectId Id { get; private set; } /// /// Gets or sets the name. /// public string Name { get; private set; } = string.Empty; /// /// Gets or sets the age. /// public int Age { get; private set; } /// /// Gets or sets the created at. /// public DateTime CreatedAt { get; private set; } // Factory method for creation /// /// Executes the create operation. /// /// The name. /// The age. public static EntityWithPrivateSetters Create(string name, int age) { return new EntityWithPrivateSetters { Id = ObjectId.NewObjectId(), Name = name, Age = age, CreatedAt = DateTime.UtcNow }; } } /// /// Entity with init-only setters (can use object initializer) /// public class EntityWithInitSetters { /// /// Gets or sets the id. /// public ObjectId Id { get; init; } /// /// Gets or sets the name. /// public required string Name { get; init; } /// /// Gets or sets the age. /// public int Age { get; init; } /// /// Gets or sets the created at. /// public DateTime CreatedAt { get; init; } } // ======================================== // Circular Reference Test Entities // ======================================== /// /// Employee with self-referencing via ObjectIds (organizational hierarchy) /// Tests: self-reference using referencing (BEST PRACTICE) /// Recommended: Avoids embedding which can lead to large/circular documents /// public class Employee { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; /// /// Gets or sets the department. /// public string Department { get; set; } = string.Empty; /// /// Gets or sets the manager id. /// public ObjectId? ManagerId { get; set; } // Reference to manager /// /// Gets or sets the direct report ids. /// public List? DirectReportIds { get; set; } // References to direct reports (best practice) } /// /// Category with referenced products (N-N using ObjectId references) /// Tests: N-N relationships using referencing (BEST PRACTICE for document databases) /// Recommended: Avoids large documents, better for queries and updates /// public class CategoryRef { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; /// /// Gets or sets the description. /// public string Description { get; set; } = string.Empty; /// /// Gets or sets the product ids. /// public List? ProductIds { get; set; } // Only IDs - no embedding } /// /// Product with referenced categories (N-N using ObjectId references) /// Tests: N-N relationships using referencing (BEST PRACTICE for document databases) /// Recommended: Avoids large documents, better for queries and updates /// public class ProductRef { /// /// Gets or sets the id. /// public ObjectId Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; /// /// Gets or sets the price. /// public decimal Price { get; set; } /// /// Gets or sets the category ids. /// public List? CategoryIds { get; set; } // Only IDs - no embedding } // ======================================== // Nullable String Key Test (UuidEntity scenario) // ======================================== /// /// Base entity class that simulates CleanCore's BaseEntity{TId, TEntity} /// This is the root of the hierarchy that causes the generator bug /// public abstract class MockBaseEntity where TId : IEquatable where TEntity : class { /// /// Gets or sets the id. /// [System.ComponentModel.DataAnnotations.Key] public virtual TId? Id { get; set; } /// /// Initializes a new instance. /// protected MockBaseEntity() { } /// /// Initializes a new instance. /// /// The id. protected MockBaseEntity(TId? id) { Id = id; } } /// /// Simulates CleanCore's UuidEntity{TEntity} which inherits from BaseEntity{string, TEntity} /// Tests the bug where generator incorrectly chooses ObjectIdMapperBase instead of StringMapperBase /// when the Id property is inherited and nullable /// public abstract class MockUuidEntity : MockBaseEntity where TEntity : class { /// /// Initializes a new instance. /// protected MockUuidEntity() : base() { } /// /// Initializes a new instance. /// /// The id. protected MockUuidEntity(string? id) : base(id) { } } /// /// Concrete entity that inherits from MockUuidEntity, simulating Counter from CleanCore /// This is the actual entity that will be stored in the collection /// public class MockCounter : MockUuidEntity { /// /// Initializes a new instance. /// public MockCounter() : base() { } /// /// Initializes a new instance. /// /// The id. public MockCounter(string? id) : base(id) { } /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; /// /// Gets or sets the value. /// public int Value { get; set; } } /// /// Entity for testing temporal types: DateTimeOffset, TimeSpan, DateOnly, TimeOnly /// public class TemporalEntity { /// /// Gets or sets the id. /// [Key] public ObjectId Id { get; set; } /// /// Gets or sets the name. /// public string Name { get; set; } = string.Empty; // DateTime types /// /// Gets or sets the created at. /// public DateTime CreatedAt { get; set; } /// /// Gets or sets the updated at. /// public DateTimeOffset UpdatedAt { get; set; } /// /// Gets or sets the last accessed at. /// public DateTimeOffset? LastAccessedAt { get; set; } // TimeSpan /// /// Gets or sets the duration. /// public TimeSpan Duration { get; set; } /// /// Gets or sets the optional duration. /// public TimeSpan? OptionalDuration { get; set; } // DateOnly and TimeOnly (.NET 6+) /// /// Gets or sets the birth date. /// public DateOnly BirthDate { get; set; } /// /// Gets or sets the anniversary. /// public DateOnly? Anniversary { get; set; } /// /// Gets or sets the opening time. /// public TimeOnly OpeningTime { get; set; } /// /// Gets or sets the closing time. /// public TimeOnly? ClosingTime { get; set; } } }