Instantly share code, notes, and snippets.
Created
March 25, 2019 13:58
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save ilyvion/22b7491fc225a1059df844505160160e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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