Skip to content

Instantly share code, notes, and snippets.

@ilyvion
Created March 25, 2019 13:58
Show Gist options
  • Save ilyvion/22b7491fc225a1059df844505160160e to your computer and use it in GitHub Desktop.
Save ilyvion/22b7491fc225a1059df844505160160e to your computer and use it in GitHub Desktop.
<Query Kind="Program">
<NuGetReference>Microsoft.EntityFrameworkCore</NuGetReference>
<NuGetReference>Microsoft.EntityFrameworkCore.InMemory</NuGetReference>
<Namespace>Microsoft.EntityFrameworkCore</Namespace>
<Namespace>Microsoft.EntityFrameworkCore.Metadata.Builders</Namespace>
<Namespace>System.Globalization</Namespace>
</Query>
void Main()
{
var options = new DbContextOptionsBuilder<TestCaseDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
CreateDatabase(options);
DirectQuery(options);
NavigationQuery(options);
NavigationQueryWithInclude(options);
NavigationQueryWithIncludeThenSelectParent(options);
EntryCollectionQuery(options);
EntryCollectionQueryWithInclude(options);
EntryCollectionQueryWithIncludeThenSelectParent(options);
EntryCollectionWithExplicitSelectQuery(options);
}
void DirectQuery(DbContextOptions<TestCaseDbContext> options)
{
var context = new TestCaseDbContext(options);
context.Items.Where(i => i.Id == 5).Dump(nameof(DirectQuery));
}
void NavigationQuery(DbContextOptions<TestCaseDbContext> options)
{
var context = new TestCaseDbContext(options);
var its = context.Occurrences.Where(o => o.OrderId == 1).Select(o => o.Item);
its.Dump(nameof(NavigationQuery));
}
void NavigationQueryWithInclude(DbContextOptions<TestCaseDbContext> options)
{
var context = new TestCaseDbContext(options);
var its = context.Occurrences.Where(o => o.OrderId == 1).Include(o => o.Item).Select(o => o.Item);
its.Dump(nameof(NavigationQueryWithInclude));
}
void NavigationQueryWithIncludeThenSelectParent(DbContextOptions<TestCaseDbContext> options)
{
var context = new TestCaseDbContext(options);
var its = context.Occurrences.Where(o => o.OrderId == 1).Include(o => o.Item);
its.Dump(nameof(NavigationQueryWithIncludeThenSelectParent));
}
void EntryCollectionQuery(DbContextOptions<TestCaseDbContext> options)
{
var context = new TestCaseDbContext(options);
var c = context.Orders.Find(1);
var its = context.Entry(c)
.Collection(co => co.Occurrences)
.Query()
.Select(o => o.Item);
its.Dump(nameof(EntryCollectionQuery));
}
void EntryCollectionQueryWithInclude(DbContextOptions<TestCaseDbContext> options)
{
var context = new TestCaseDbContext(options);
var c = context.Orders.Find(1);
var its = context.Entry(c)
.Collection(co => co.Occurrences)
.Query()
.Include(o => o.Item.Color)
.Select(o => o.Item);
its.Dump(nameof(EntryCollectionQueryWithInclude));
}
void EntryCollectionQueryWithIncludeThenSelectParent(DbContextOptions<TestCaseDbContext> options)
{
var context = new TestCaseDbContext(options);
var c = context.Orders.Find(1);
var its = context.Entry(c)
.Collection(co => co.Occurrences)
.Query()
.Include(o => o.Item);
its.ToList().Select(o => o.Item).Dump(nameof(EntryCollectionQueryWithIncludeThenSelectParent));
}
void EntryCollectionWithExplicitSelectQuery(DbContextOptions<TestCaseDbContext> options)
{
var context = new TestCaseDbContext(options);
var c = context.Orders.Find(1);
var its = context.Entry(c)
.Collection(co => co.Occurrences)
.Query()
.Select(o => new Item { Id = o.Item.Id, Name = o.Item.Name, Color = o.Item.Color });
its.Dump(nameof(EntryCollectionWithExplicitSelectQuery));
}
void CreateDatabase(DbContextOptions<TestCaseDbContext> options)
{
var context = new TestCaseDbContext(options);
context.Database.EnsureCreated();
context.Orders.AddRange(new[] {
new Order { Id = 1, Title = "Order 1" },
new Order { Id = 2, Title = "Order 2" },
new Order { Id = 3, Title = "Order 3" },
new Order { Id = 4, Title = "Order 4" },
new Order { Id = 5, Title = "Order 5" },
});
context.Items.AddRange(new[] {
new Item{ Id = 1, Name = "Item 1", Color = (HexRgbColor)"123456" },
new Item{ Id = 2, Name = "Item 2", Color = (HexRgbColor)"234567" },
new Item{ Id = 3, Name = "Item 3", Color = (HexRgbColor)"345678" },
new Item{ Id = 4, Name = "Item 4", Color = (HexRgbColor)"456789" },
new Item{ Id = 5, Name = "Item 5", Color = (HexRgbColor)"56789A" },
});
context.Occurrences.AddRange(new[] {
new Occurrence { OrderId = 1, ItemId = 5 },
new Occurrence { OrderId = 2, ItemId = 4 },
new Occurrence { OrderId = 3, ItemId = 3 },
new Occurrence { OrderId = 4, ItemId = 2 },
new Occurrence { OrderId = 5, ItemId = 1 },
});
context.SaveChanges();
}
// Define other methods and classes here
// Source: https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/implement-value-objects
public abstract class ValueObject
{
protected static bool EqualOperator(ValueObject left, ValueObject right)
{
if (left is null ^ right is null)
{
return false;
}
return left?.Equals(right) != false;
}
protected static bool NotEqualOperator(ValueObject left, ValueObject right)
{
return !(EqualOperator(left, right));
}
protected abstract IEnumerable<object> GetAtomicValues();
public override bool Equals(object obj)
{
if (obj == null || obj.GetType() != GetType())
{
return false;
}
var other = (ValueObject)obj;
var thisValues = GetAtomicValues().GetEnumerator();
var otherValues = other.GetAtomicValues().GetEnumerator();
while (thisValues.MoveNext() && otherValues.MoveNext())
{
if (thisValues.Current is null ^ otherValues.Current is null)
{
return false;
}
if (thisValues.Current != null &&
!thisValues.Current.Equals(otherValues.Current))
{
return false;
}
}
return !thisValues.MoveNext() && !otherValues.MoveNext();
}
public override int GetHashCode()
{
return GetAtomicValues()
.Select(x => x != null ? x.GetHashCode() : 0)
.Aggregate((x, y) => x ^ y);
}
}
public class HexRgbColor : ValueObject
{
private HexRgbColor()
{
}
public static HexRgbColor For(string hexRgbColorString)
{
var color = new HexRgbColor();
try
{
color.Red = byte.Parse(hexRgbColorString.Substring(0, 2), NumberStyles.HexNumber);
color.Green = byte.Parse(hexRgbColorString.Substring(2, 2), NumberStyles.HexNumber);
color.Blue = byte.Parse(hexRgbColorString.Substring(4, 2), NumberStyles.HexNumber);
}
catch (Exception ex)
{
throw new Exception(hexRgbColorString, ex);
}
return color;
}
public byte Red { get; private set; }
public byte Green { get; private set; }
public byte Blue { get; private set; }
public static implicit operator string(HexRgbColor color)
{
return color.ToString();
}
public static explicit operator HexRgbColor(string hexRgbColorString)
{
return For(hexRgbColorString);
}
public override string ToString()
{
return $"{Red:X2}{Green:X2}{Blue:X2}";
}
protected override IEnumerable<object> GetAtomicValues()
{
yield return Red;
yield return Green;
yield return Blue;
}
}
public class Item
{
public Item()
{
Occurrences = new HashSet<Occurrence>();
}
public int Id { get; set; }
public string Name { get; set; }
public HexRgbColor Color { get; set; } = (HexRgbColor)"7F7F7F";
public ICollection<Occurrence> Occurrences { get; private set; }
}
public class Occurrence
{
public int OrderId { get; set; }
public Order Order { get; set; }
public int ItemId { get; set; }
public Item Item { get; set; }
}
public class Order
{
public Order()
{
Occurrences = new HashSet<Occurrence>();
}
public int Id { get; set; }
public string Title { get; set; }
public ICollection<Occurrence> Occurrences { get; private set; }
}
public abstract class DomainDbContext : DbContext
{
public DomainDbContext(DbContextOptions options) : base(options) { }
protected DomainDbContext() { }
public DbSet<Order> Orders { get; set; }
public DbSet<Item> Items { get; set; }
public DbSet<Occurrence> Occurrences { get; set; }
}
public class TestCaseDbContext : DomainDbContext
{
public TestCaseDbContext(DbContextOptions<TestCaseDbContext> options) : base(options) { }
protected TestCaseDbContext() { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(TestCaseDbContext).Assembly);
}
}
public class OrderConfiguration : IEntityTypeConfiguration<Order>
{
public void Configure(EntityTypeBuilder<Order> orderBuilder)
{
orderBuilder.HasKey(o => o.Id);
orderBuilder.Property(o => o.Id);
orderBuilder.Property(o => o.Title)
.IsRequired()
.HasMaxLength(255);
}
}
public class ItemConfiguration : IEntityTypeConfiguration<Item>
{
public void Configure(EntityTypeBuilder<Item> itemBuilder)
{
itemBuilder.HasKey(i => i.Id);
itemBuilder.Property(i => i.Id);
itemBuilder.Property(i => i.Name)
.HasMaxLength(255)
.IsRequired();
itemBuilder.OwnsOne(i => i.Color);
}
}
public class OccurrenceConfiguration : IEntityTypeConfiguration<Occurrence>
{
public void Configure(EntityTypeBuilder<Occurrence> occurrenceBuilder)
{
occurrenceBuilder.HasKey(o => new { o.OrderId, o.ItemId });
occurrenceBuilder.Property(o => o.OrderId);
occurrenceBuilder.Property(o => o.ItemId);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment