Created
November 6, 2020 08:11
-
-
Save danielplawgo/9bfbea4c1038b88659e7ca4d34e8c605 to your computer and use it in GitHub Desktop.
Optymistyczna współbieżność w EF Core
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
public class DataContext : DbContext | |
{ | |
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) | |
{ | |
optionsBuilder.UseSqlServer(@"Server=.\SQLEXPRESS;Database=EFCoreOptimisticConcurrency;Trusted_Connection=True;"); | |
} | |
public DbSet<Product> Products { get; set; } | |
} |
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
public class DataContext : DbContext | |
{ | |
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) | |
{ | |
optionsBuilder.UseSqlServer(@"Server=.\SQLEXPRESS;Database=EFCoreOptimisticConcurrency;Trusted_Connection=True;"); | |
} | |
protected override void OnModelCreating(ModelBuilder modelBuilder) | |
{ | |
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); | |
} | |
public DbSet<Product> Products { get; set; } | |
} |
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
private static async Task EditProduct(Guid productId, Action<Product> editAction, int delay) | |
{ | |
await using var db = new DataContext(); | |
var product = await db.Products.FirstOrDefaultAsync(p => p.Id == productId); | |
await Task.Delay(delay); | |
editAction(product); | |
await db.SaveChangesAsync(); | |
} |
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
private static async Task EditProduct(Guid productId, Action<Product> editAction, int delay) | |
{ | |
await using var db = new DataContext(); | |
try | |
{ | |
var product = await db.Products.FirstOrDefaultAsync(p => p.Id == productId); | |
await Task.Delay(delay); | |
editAction(product); | |
await db.SaveChangesAsync(); | |
} | |
catch (DbUpdateConcurrencyException ex) | |
{ | |
foreach (var entry in ex.Entries) | |
{ | |
var databaseValues = await entry.GetDatabaseValuesAsync(); | |
foreach (var property in entry.CurrentValues.Properties) | |
{ | |
var proposedValue = entry.CurrentValues[property]; | |
var databaseValue = databaseValues[property]; | |
var originalValue = entry.OriginalValues[property]; | |
if (proposedValue.Equals(databaseValue) || originalValue.Equals(databaseValue) || property.Name == "RowVersion") | |
{ | |
continue; | |
} | |
Console.WriteLine($"ProposedValue: {proposedValue}, DatabaseValue: {databaseValue}, OriginalValue: {originalValue}."); | |
//proposedValues[property] = wartość do zapisu; | |
} | |
entry.OriginalValues.SetValues(databaseValues); | |
} | |
} | |
} |
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
static async Task Main(string[] args) | |
{ | |
var productId = Guid.Parse("E440B325-AD1F-4B4D-9162-36DFB0F3A357"); | |
await Setup(productId); | |
var tasks = new[] | |
{ | |
EditProduct(productId, p => p.Price = 11, 1000), | |
EditProduct(productId, p => p.Price = 12, 100) | |
}; | |
await Task.WhenAll(tasks); | |
var product = await GetProduct(productId); | |
Console.WriteLine($"Product: {product.Name}, price: {product.Price}"); | |
} |
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
EditProduct(productId, p => p.Price = 11, 1000), | |
EditProduct(productId, p => p.Name = "new product", 100) |
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
public class Product | |
{ | |
public Guid Id { get; set; } = Guid.NewGuid(); | |
public string Name { get; set; } | |
public decimal Price { get; set; } | |
} |
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
public class Product | |
{ | |
public Guid Id { get; set; } = Guid.NewGuid(); | |
public string Name { get; set; } | |
public decimal Price { get; set; } | |
public byte[] RowVersion { get; set; } | |
} |
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
public class ProductEntityTypeConfiguration : IEntityTypeConfiguration<Product> | |
{ | |
public void Configure(EntityTypeBuilder<Product> builder) | |
{ | |
builder.Property(p => p.RowVersion) | |
.IsRowVersion(); | |
} | |
} |
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
private static async Task Setup(Guid productId) | |
{ | |
await using var db = new DataContext(); | |
var product = await db.Products.FirstOrDefaultAsync(p => p.Id == productId); | |
if (product == null) | |
{ | |
product = new Product() | |
{ | |
Id = productId | |
}; | |
await db.Products.AddAsync(product); | |
} | |
product.Name = "product"; | |
product.Price = 10; | |
await db.SaveChangesAsync(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment