You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.9 KiB
C#
145 lines
4.9 KiB
C#
|
6 years ago
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||
|
|
|
||
|
|
using System;
|
||
|
|
using System.Linq;
|
||
|
|
using EntityFrameworkCore.Jet.FunctionalTests.TestUtilities;
|
||
|
|
using Microsoft.EntityFrameworkCore;
|
||
|
|
using Microsoft.EntityFrameworkCore.TestUtilities;
|
||
|
|
using Xunit;
|
||
|
|
|
||
|
|
// ReSharper disable InconsistentNaming
|
||
|
|
namespace EntityFrameworkCore.Jet.FunctionalTests
|
||
|
|
{
|
||
|
|
public class JetQueryTriggersTest : IClassFixture<JetQueryTriggersTest.JetTriggersFixture>
|
||
|
|
{
|
||
|
|
public JetQueryTriggersTest(JetTriggersFixture fixture) => Fixture = fixture;
|
||
|
|
|
||
|
|
private JetTriggersFixture Fixture { get; }
|
||
|
|
|
||
|
|
[ConditionalFact]
|
||
|
|
public void Triggers_with_subqueries_run_on_insert_update_and_delete()
|
||
|
|
{
|
||
|
|
using (var context = CreateContext())
|
||
|
|
{
|
||
|
|
var product = new Product { Name = "blah" };
|
||
|
|
context.Products.Add(product);
|
||
|
|
context.SaveChanges();
|
||
|
|
|
||
|
|
Assert.Equal(1, product.StoreUpdated);
|
||
|
|
|
||
|
|
product.Name = "fooh";
|
||
|
|
context.SaveChanges();
|
||
|
|
|
||
|
|
Assert.Equal(2, product.StoreUpdated);
|
||
|
|
|
||
|
|
context.Products.Remove(product);
|
||
|
|
context.SaveChanges();
|
||
|
|
|
||
|
|
Assert.Empty(context.Products);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[ConditionalFact]
|
||
|
|
public void Triggers_with_subqueries_work_with_batch_operations()
|
||
|
|
{
|
||
|
|
using (var context = CreateContext())
|
||
|
|
{
|
||
|
|
var productToBeUpdated1 = new Product { Name = "u1" };
|
||
|
|
var productToBeUpdated2 = new Product { Name = "u2" };
|
||
|
|
context.Products.Add(productToBeUpdated1);
|
||
|
|
context.Products.Add(productToBeUpdated2);
|
||
|
|
|
||
|
|
var productToBeDeleted1 = new Product { Name = "d1" };
|
||
|
|
var productToBeDeleted2 = new Product { Name = "d2" };
|
||
|
|
context.Products.Add(productToBeDeleted1);
|
||
|
|
context.Products.Add(productToBeDeleted2);
|
||
|
|
|
||
|
|
context.SaveChanges();
|
||
|
|
|
||
|
|
var productToBeAdded1 = new Product { Name = "a1" };
|
||
|
|
var productToBeAdded2 = new Product { Name = "a2" };
|
||
|
|
context.Products.Add(productToBeAdded1);
|
||
|
|
context.Products.Add(productToBeAdded2);
|
||
|
|
|
||
|
|
productToBeUpdated1.Name = "n1";
|
||
|
|
productToBeUpdated2.Name = "n2";
|
||
|
|
|
||
|
|
context.Products.Remove(productToBeDeleted1);
|
||
|
|
context.Products.Remove(productToBeDeleted2);
|
||
|
|
|
||
|
|
context.SaveChanges();
|
||
|
|
|
||
|
|
Assert.Equal(1, productToBeAdded1.StoreUpdated);
|
||
|
|
Assert.Equal(1, productToBeAdded2.StoreUpdated);
|
||
|
|
Assert.Equal(2, productToBeUpdated1.StoreUpdated);
|
||
|
|
Assert.Equal(2, productToBeUpdated2.StoreUpdated);
|
||
|
|
|
||
|
|
var products = context.Products.ToList();
|
||
|
|
Assert.Equal(4, products.Count);
|
||
|
|
|
||
|
|
context.Products.RemoveRange(products);
|
||
|
|
|
||
|
|
context.SaveChanges();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
protected QueryTriggersContext CreateContext() => (QueryTriggersContext)Fixture.CreateContext();
|
||
|
|
|
||
|
|
protected class QueryTriggersContext : PoolableDbContext
|
||
|
|
{
|
||
|
|
public QueryTriggersContext(DbContextOptions options)
|
||
|
|
: base(options)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual DbSet<Product> Products { get; set; }
|
||
|
|
|
||
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||
|
|
{
|
||
|
|
modelBuilder.Entity<Product>(
|
||
|
|
eb =>
|
||
|
|
{
|
||
|
|
eb.Property(e => e.StoreUpdated)
|
||
|
|
.HasDefaultValue(0)
|
||
|
|
.ValueGeneratedOnAddOrUpdate();
|
||
|
|
eb.ToTable("UpdatedProducts");
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
protected class Product
|
||
|
|
{
|
||
|
|
public virtual int Id { get; set; }
|
||
|
|
public virtual byte[] Version { get; set; }
|
||
|
|
public virtual string Name { get; set; }
|
||
|
|
public virtual int StoreUpdated { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
public class JetTriggersFixture : SharedStoreFixtureBase<DbContext>
|
||
|
|
{
|
||
|
|
protected override string StoreName { get; } = "JetQueryTriggers";
|
||
|
|
protected override Type ContextType { get; } = typeof(QueryTriggersContext);
|
||
|
|
protected override ITestStoreFactory TestStoreFactory => JetTestStoreFactory.Instance;
|
||
|
|
|
||
|
|
protected override void Seed(DbContext context)
|
||
|
|
{
|
||
|
|
context.Database.EnsureCreatedResiliently();
|
||
|
|
|
||
|
|
context.Database.ExecuteSqlRaw(
|
||
|
|
@"
|
||
|
|
CREATE TRIGGER TRG_InsertUpdateProduct
|
||
|
|
ON UpdatedProducts
|
||
|
|
AFTER INSERT, UPDATE AS
|
||
|
|
BEGIN
|
||
|
|
IF @@ROWCOUNT = 0
|
||
|
|
return
|
||
|
|
SET nocount on;
|
||
|
|
|
||
|
|
UPDATE UpdatedProducts set StoreUpdated = StoreUpdated + 1
|
||
|
|
WHERE Id IN(SELECT INSERTED.Id FROM INSERTED);
|
||
|
|
END");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|