856 lines
50 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using gehGassi.Core.Interfaces;
using gehGassi.Domain.Advertisements;
using gehGassi.Domain.Coins;
using gehGassi.Domain.Common;
using gehGassi.Domain.Customers;
using gehGassi.Domain.Devices;
using gehGassi.Domain.Dogs;
using gehGassi.Domain.Favourites;
using gehGassi.Domain.Feedback;
using gehGassi.Domain.Messages;
using gehGassi.Domain.News;
using gehGassi.Domain.Pages;
using gehGassi.Domain.Payment;
using gehGassi.Domain.Ratings;
using gehGassi.Domain.Reporting;
using gehGassi.Domain.Roles;
using gehGassi.Domain.Shop;
using gehGassi.Domain.Subscriptions;
using gehGassi.Domain.Users;
using gehGassi.Domain.Vouchers;
using gehGassi.Domain.Walks;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
namespace gehGassi.Persistence
{
/// <summary>
/// Basis Datenbank Kontext für SQL-Server. Implementiert IUnitOfWork.
/// </summary>
public class SqlDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>, IAuditDbContext
{
private readonly AuditOptions _auditOptions;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="options">Optionen</param>
/// <param name="auditOptions">Audit-Optionen</param>
public SqlDbContext(DbContextOptions<SqlDbContext> options, IOptions<AuditOptions> auditOptions) : base(options)
{
_auditOptions = auditOptions.Value;
}
public DbSet<Audit> Audits { get; set; }
public DbSet<FidoStoredCredential> FidoStoredCredentials { get; set; }
public DbSet<RefreshToken> RefreshTokens { get; set; }
public DbSet<PersistedTicket> PersistedTickets { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<CustomerType> CustomerTypes { get; set; }
public DbSet<AppUser> AppUsers { get; set; }
public DbSet<DogWalkerProfile> DogWalkerProfiles { get; set; }
public DbSet<Certificate> Certificates { get; set; }
public DbSet<AppUserBlock> AppUserBlocks { get; set; }
public DbSet<Dog> Dogs { get; set; }
public DbSet<TaxRate> TaxRates { get; set; }
public DbSet<AdvertisementCategory> AdvertisementCategories { get; set; }
public DbSet<Advertisement> Advertisements { get; set; }
public DbSet<Listing> Listings { get; set; }
public DbSet<Branch> Branches { get; set; }
public DbSet<Banner> Banners { get; set; }
public DbSet<BannerStatistic> BannerStatistics { get; set; }
public DbSet<Pin> Pins { get; set; }
public DbSet<ShopSettings> ShopSettings { get; set; }
public DbSet<ShipmentCost> ShipmentCosts { get; set; }
public DbSet<Cart> Carts { get; set; }
public DbSet<CartItem> CartItems { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }
public DbSet<Invoice> Invoices { get; set; }
public DbSet<CreditNote> CreditNotes { get; set; }
public DbSet<DeliveryNote> DeliveryNotes { get; set; }
public DbSet<ProductCategory> ProductCategories { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<ProductCountry> ProductCountries { get; set; }
public DbSet<DogRace> DogRaces { get; set; }
public DbSet<NewsCategory> NewsCategories { get; set; }
public DbSet<News> News { get; set; }
public DbSet<Page> Pages { get; set; }
public DbSet<Faq> Faqs { get; set; }
public DbSet<AppUserRelation> EntityRelations { get; set; }
public DbSet<Conversation> Conversations { get; set; }
public DbSet<Message> Messages { get; set; }
public DbSet<MessageCopy> MessageCopies { get; set; }
public DbSet<PublicWalkRequest> PublicWalkRequests { get; set; }
public DbSet<PublicWalkResponse> PublicWalkResponses { get; set; }
public DbSet<PublicWalkRequestNotification> PublicWalkRequestNotifications { get; set; }
public DbSet<Walk> Walks { get; set; }
public DbSet<WalkingTime> WalkingTimes { get; set; }
public DbSet<WalkComplaint> WalkComplaints { get; set; }
public DbSet<Rating> Ratings { get; set; }
public DbSet<AppFeedback> AppFeedbacks { get; set; }
public DbSet<Favourite> Favourites { get; set; }
public DbSet<SystemMessage> SystemMessages { get; set; }
public DbSet<SystemMessageToSend> SystemMessagesToSend { get; set; }
public DbSet<Device> Devices { get; set; }
public DbSet<Wallet> Wallets { get; set; }
public DbSet<TransactionFee> TransactionFees { get; set; }
public DbSet<GehGassiFee> GehGassiFees { get; set; }
public DbSet<PaymentTransaction> PaymentTransactions { get; set; }
public DbSet<IdentityDocument> IdentityDocuments { get; set; }
public DbSet<Payout> Payouts { get; set; }
public DbSet<Card> Cards { get; set; }
public DbSet<AppUserReport> AppUserReports { get; set; }
public DbSet<CoinsAccount> CoinsAccounts { get; set; }
public DbSet<CoinsTransaction> CoinsTransactions { get; set; }
public DbSet<CoinsPerMonth> CoinsPerMonths { get; set; }
public DbSet<CoinsPerYear> CoinsPerYears { get; set; }
public DbSet<AppVersion> AppVersions { get; set; }
public DbSet<VoucherCampaign> VoucherCampaigns { get; set; }
public DbSet<Voucher> Vouchers { get; set; }
public DbSet<VoucherUsage> VoucherUsages { get; set; }
public DbSet<Subscription> Subscriptions { get; set; }
public DbSet<AppUserSubscription> AppUserSubscriptions { get; set; }
//Views
public DbSet<AuditWithNames> AuditsWithNames { get; set; }
public DbSet<ApplicationUserWithNames> ApplicationUsersWithNames { get; set; }
public DbSet<CustomerWithNames> CustomerWithNames { get; set; }
public DbSet<OrderPhysical> OrdersPhysical { get; set; }
public DbSet<DogWalker> DogWalkers { get; set; }
public DbSet<RatingWithNames> RatingsWithNames { get; set; }
public DbSet<AppUserReportWithNames> AppUserReportsWithNames { get; set; }
public DbSet<ConversationWithNames> ConversationsWithNames { get; set; }
public DbSet<CoinsPerMonthWithNames> CoinsPerMonthWithNames { get; set; }
public DbSet<CoinsPerYearWithNames> CoinsPerYearWithNames { get; set; }
//Table-Value Functions
public DbSet<AdvertisementCategoryWithNames> AdvertisementCategoriesWithNames { get; set; }
public DbSet<ProductCategoryWithNames> ProductCategoriesWithNames { get; set; }
public DbSet<TaxRateWithNames> TaxRatesWithNames { get; set; }
public DbSet<ProductWithNames> ProductsWithNames { get; set; }
public DbSet<ProductWithNamesCountry> ProductsWithNamesCountry { get; set; }
public DbSet<CartItemWithNames> CartItemsWithNames { get; set; }
public DbSet<CartWithNames> CartsWithNames { get; set; }
public DbSet<BranchWithNames> BranchesWithNames { get; set; }
public DbSet<ListingWithNames> ListingsWithNames { get; set; }
public DbSet<AdvertisementWithNames> AdvertisementsWithNames { get; set; }
public DbSet<BannerWithNames> BannersWithNames { get; set; }
public DbSet<PinWithNames> PinsWithNames { get; set; }
public DbSet<DogRaceWithNames> DogRacesWithNames { get; set; }
public DbSet<DogWithNames> DogWithNames { get; set; }
public DbSet<NewsCategoryWithNames> NewsCategoriesWithNames { get; set; }
public DbSet<NewsWithNames> NewsWithNames { get; set; }
public DbSet<ConversationWithTarget> ConversationsWithTarget { get; set; }
public DbSet<PageWithNames> PagesWithNames { get; set; }
public DbSet<FaqWithNames> FaqsWithNames { get; set; }
public DbSet<PublicWalkRequestWithNames> PublicWalkRequestWithNames { get; set; }
public DbSet<PublicWalkRequestWithNamesAndResponseStatus> PublicWalkRequestsWithNamesAndResponseStatus { get; set; }
public DbSet<PublicWalkResponseWithNames> PublicWalkResponsesWithNames { get; set; }
public DbSet<WalkWithNames> WalksWithNames { get; set; }
public DbSet<WalkComplaintWithNames> WalkComplaintsWithNames { get; set; }
public DbSet<AppUserBlockWithNames> AppUserBlocksWithNames { get; set; }
public DbSet<RatingWithNamesEx> RatingsWithNamesEx { get; set; }
public DbSet<AppVersionWithNames> AppVersionsWithNames { get; set; }
public DbSet<VoucherCampaignWithNames> VoucherCampaignsWithNames { get; set; }
public DbSet<SubscriptionWithNames> SubscriptionWithNames { get; set; }
public DbSet<AppUserSubscriptionWithNames> AppUserSubscriptionWithNames { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
builder.Entity<ApplicationUser>().HasOne<Customer>().WithMany().HasForeignKey(c => c.CustomerId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<ApplicationUser>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Customer>().OwnsOne(p => p.Address);
builder.Entity<Customer>().OwnsOne(p => p.Contact);
builder.Entity<Customer>().HasOne<CustomerType>().WithMany().HasForeignKey(c => c.TypeId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Customer>().HasOne<Branch>().WithMany().HasForeignKey(c => c.BranchId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Customer>().Property(c => c.MarkupListing).HasColumnType("decimal(18,2)");
builder.Entity<Customer>().Property(c => c.MarkupAdvertisement).HasColumnType("decimal(18,2)");
builder.Entity<Customer>().Property(c => c.MarkupPin).HasColumnType("decimal(18,2)");
builder.Entity<Customer>().Property(c => c.MarkupBanner).HasColumnType("decimal(18,2)");
builder.Entity<Customer>().OwnsOne(c => c.MangopayAddress, d => d.ToJson());
builder.Entity<TaxRate>().Property(c => c.Value).HasColumnType("decimal(18,2)");
builder.Entity<ShipmentCost>().Property(c => c.WeightFrom).HasColumnType("decimal(18,2)");
builder.Entity<ShipmentCost>().Property(c => c.WeightTo).HasColumnType("decimal(18,2)");
builder.Entity<ShipmentCost>().Property(c => c.SubtotalFrom).HasColumnType("decimal(18,2)");
builder.Entity<ShipmentCost>().Property(c => c.SubtotalTo).HasColumnType("decimal(18,2)");
builder.Entity<ShipmentCost>().Property(c => c.FixedPrice).HasColumnType("decimal(18,4)");
builder.Entity<ShipmentCost>().Property(c => c.SubtotalPercent).HasColumnType("decimal(18,2)");
builder.Entity<Cart>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Cart>().HasOne<Customer>().WithMany().HasForeignKey(c => c.CustomerId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Cart>().Property(c => c.Total).HasColumnType("decimal(18,2)");
builder.Entity<Cart>().Property(c => c.TotalGross).HasColumnType("decimal(18,2)");
builder.Entity<Cart>().Property(c => c.Shipment).HasColumnType("decimal(18,2)");
builder.Entity<Cart>().Property(c => c.ShipmentGross).HasColumnType("decimal(18,2)");
builder.Entity<CartItem>().HasOne<Cart>().WithMany().HasForeignKey(c => c.CartId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<CartItem>().HasOne<Product>().WithMany().HasForeignKey(c => c.ProductId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<CartItem>().Property(c => c.Price).HasColumnType("decimal(18,4)");
builder.Entity<CartItem>().Property(c => c.Price2).HasColumnType("decimal(18,4)");
builder.Entity<CartItem>().Property(c => c.PriceGross).HasColumnType("decimal(18,2)");
builder.Entity<CartItem>().Property(c => c.Price2Gross).HasColumnType("decimal(18,2)");
builder.Entity<CartItem>().Property(c => c.Total).HasColumnType("decimal(18,2)");
builder.Entity<CartItem>().Property(c => c.TotalGross).HasColumnType("decimal(18,2)");
builder.Entity<CartItem>().Property(c => c.TaxRate).HasColumnType("decimal(18,2)");
builder.Entity<CartItem>().Property(c => c.TaxRateValue).HasColumnType("decimal(18,2)");
builder.Entity<Order>().OwnsOne(p => p.DeliveryAddress);
builder.Entity<Order>().OwnsOne(p => p.BillingAddress);
builder.Entity<Order>().Property(c => c.Subtotal).HasColumnType("decimal(18,2)");
builder.Entity<Order>().Property(c => c.SubtotalGross).HasColumnType("decimal(18,2)");
builder.Entity<Order>().Property(c => c.Total).HasColumnType("decimal(18,2)");
builder.Entity<Order>().Property(c => c.TotalGross).HasColumnType("decimal(18,2)");
builder.Entity<Order>().Property(c => c.Shipment).HasColumnType("decimal(18,2)");
builder.Entity<Order>().Property(c => c.ShipmentGross).HasColumnType("decimal(18,2)");
builder.Entity<OrderItem>().HasOne<Order>().WithMany().HasForeignKey(c => c.OrderId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<OrderItem>().HasOne<Product>().WithMany().HasForeignKey(c => c.ProductId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<OrderItem>().HasOne<ProductCategory>().WithMany().HasForeignKey(c => c.ProductCategoryId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<OrderItem>().HasOne<TaxRate>().WithMany().HasForeignKey(c => c.TaxRateId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<OrderItem>().Property(c => c.AdditionalShippingCharge).HasColumnType("decimal(18,2)");
builder.Entity<OrderItem>().Property(c => c.Price).HasColumnType("decimal(18,4)");
builder.Entity<OrderItem>().Property(c => c.PriceGross).HasColumnType("decimal(18,2)");
builder.Entity<OrderItem>().Property(c => c.Price2).HasColumnType("decimal(18,4)");
builder.Entity<OrderItem>().Property(c => c.Price2Gross).HasColumnType("decimal(18,2)");
builder.Entity<OrderItem>().Property(c => c.Total).HasColumnType("decimal(18,2)");
builder.Entity<OrderItem>().Property(c => c.TotalGross).HasColumnType("decimal(18,2)");
builder.Entity<OrderItem>().Property(c => c.Weight).HasColumnType("decimal(18,2)");
builder.Entity<OrderItem>().Property(c => c.Length).HasColumnType("decimal(18,2)");
builder.Entity<OrderItem>().Property(c => c.Width).HasColumnType("decimal(18,2)");
builder.Entity<OrderItem>().Property(c => c.Height).HasColumnType("decimal(18,2)");
builder.Entity<Invoice>().HasOne<Order>().WithMany().HasForeignKey(c => c.OrderId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<CreditNote>().HasOne<Order>().WithMany().HasForeignKey(c => c.OrderId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<DeliveryNote>().HasOne<Order>().WithMany().HasForeignKey(c => c.OrderId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<AdvertisementCategory>().HasIndex(c => c.Index);
builder.Entity<Advertisement>().HasIndex(c => c.Index);
builder.Entity<Advertisement>().OwnsOne(p => p.Address);
builder.Entity<Advertisement>().HasOne<Customer>().WithMany().HasForeignKey(c => c.CustomerId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Advertisement>().HasOne<AdvertisementCategory>().WithMany().HasForeignKey(c => c.AdvertisementCategoryId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Advertisement>().HasOne<Order>().WithMany().HasForeignKey(c => c.OrderId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Advertisement>().HasOne<OrderItem>().WithMany().HasForeignKey(c => c.OrderItemId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Advertisement>().Property(c => c.Discount).HasColumnType("decimal(18,2)");
builder.Entity<Listing>().HasIndex(c => c.Index);
builder.Entity<Listing>().OwnsOne(p => p.Address);
builder.Entity<Listing>().OwnsOne(p => p.ListingAddress);
builder.Entity<Listing>().HasOne<Customer>().WithMany().HasForeignKey(c => c.CustomerId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Listing>().HasOne<Branch>().WithMany().HasForeignKey(c => c.BranchId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Listing>().HasOne<Order>().WithMany().HasForeignKey(c => c.OrderId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Listing>().HasOne<OrderItem>().WithMany().HasForeignKey(c => c.OrderItemId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Banner>().HasIndex(c => c.Index);
builder.Entity<Banner>().OwnsOne(p => p.Address);
builder.Entity<Banner>().HasOne<Customer>().WithMany().HasForeignKey(c => c.CustomerId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Banner>().HasOne<Order>().WithMany().HasForeignKey(c => c.OrderId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Banner>().HasOne<OrderItem>().WithMany().HasForeignKey(c => c.OrderItemId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Banner>().Property(c => c.Budget).HasColumnType("decimal(18,4)");
builder.Entity<Banner>().Property(c => c.BudgetUsed).HasColumnType("decimal(18,4)");
builder.Entity<Banner>().Property(c => c.PriceView).HasColumnType("decimal(18,4)");
builder.Entity<Banner>().Property(c => c.PriceClick).HasColumnType("decimal(18,4)");
builder.Entity<BannerStatistic>().HasOne<Banner>().WithMany().HasForeignKey(c => c.BannerId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Pin>().HasIndex(c => c.Index);
builder.Entity<Pin>().HasOne<Customer>().WithMany().HasForeignKey(c => c.CustomerId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Pin>().HasOne<Listing>().WithMany().HasForeignKey(c => c.ListingId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Pin>().HasOne<Order>().WithMany().HasForeignKey(c => c.OrderId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Pin>().HasOne<OrderItem>().WithMany().HasForeignKey(c => c.OrderItemId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Product>().HasOne<ProductCategory>().WithMany().HasForeignKey(c => c.ProductCategoryId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Product>().HasOne<TaxRate>().WithMany().HasForeignKey(c => c.TaxRateId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Product>().Property(c => c.AdditionalShippingCharge).HasColumnType("decimal(18,4)");
builder.Entity<Product>().Property(c => c.Price).HasColumnType("decimal(18,4)");
builder.Entity<Product>().Property(c => c.OldPrice).HasColumnType("decimal(18,4)");
builder.Entity<Product>().Property(c => c.Price2).HasColumnType("decimal(18,4)");
builder.Entity<Product>().Property(c => c.OldPrice2).HasColumnType("decimal(18,4)");
builder.Entity<Product>().Property(c => c.Weight).HasColumnType("decimal(18,2)");
builder.Entity<Product>().Property(c => c.Length).HasColumnType("decimal(18,2)");
builder.Entity<Product>().Property(c => c.Width).HasColumnType("decimal(18,2)");
builder.Entity<Product>().Property(c => c.Height).HasColumnType("decimal(18,2)");
builder.Entity<Product>().Property(c => c.PinPercentPerKm).HasColumnType("decimal(18,2)");
builder.Entity<ProductCountry>().HasOne<Product>().WithMany().HasForeignKey(c => c.ProductId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<ProductCountry>().Property(c => c.Price).HasColumnType("decimal(18,4)");
builder.Entity<ProductCountry>().Property(c => c.OldPrice).HasColumnType("decimal(18,4)");
builder.Entity<ProductCountry>().Property(c => c.Price2).HasColumnType("decimal(18,4)");
builder.Entity<ProductCountry>().Property(c => c.OldPrice2).HasColumnType("decimal(18,4)");
builder.Entity<AppUser>().OwnsOne(p => p.Address);
builder.Entity<AppUser>().OwnsOne(p => p.Contact);
builder.Entity<AppUser>().OwnsOne(p => p.SocialMedia);
builder.Entity<AppUser>().OwnsOne(p => p.RatingStatistics, n =>
{
n.Property(m => m.AverageRating).HasColumnType("decimal(18,2)").HasDefaultValue(0);
n.Property(m => m.TotalPoints).HasColumnType("decimal(18,2)").HasDefaultValue(0);
n.Property(m => m.TotalRatings).HasDefaultValue(0);
});
builder.Entity<AppUser>().OwnsOne(p => p.RatingStatisticsWalker, n =>
{
n.Property(m => m.AverageRating).HasColumnType("decimal(18,2)").HasDefaultValue(0);
n.Property(m => m.TotalPoints).HasColumnType("decimal(18,2)").HasDefaultValue(0);
n.Property(m => m.TotalRatings).HasDefaultValue(0);
});
builder.Entity<AppUser>().HasIndex(c => c.Index);
builder.Entity<DogWalkerProfile>().HasIndex(c => c.Index);
builder.Entity<DogWalkerProfile>().Property(c => c.PriceWalk).HasColumnType("decimal(18,2)");
builder.Entity<DogWalkerProfile>().Property(c => c.PriceDay).HasColumnType("decimal(18,2)");
builder.Entity<DogWalkerProfile>().Property(c => c.PriceSitting).HasColumnType("decimal(18,2)");
builder.Entity<Certificate>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<AppUserBlock>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.BlockingAppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<AppUserBlock>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.BlockedAppUserId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Dog>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Dog>().HasOne<DogRace>().WithMany().HasForeignKey(c => c.DogRaceId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<Dog>().OwnsOne(p => p.RatingStatistics, n =>
{
n.Property(m => m.AverageRating).HasColumnType("decimal(18,2)").HasDefaultValue(0);
n.Property(m => m.TotalPoints).HasColumnType("decimal(18,2)").HasDefaultValue(0);
n.Property(m => m.TotalRatings).HasDefaultValue(0);
});
builder.Entity<Dog>().HasIndex(c => c.Index);
builder.Entity<DogRace>().HasIndex(c => c.Index);
builder.Entity<NewsCategory>().HasIndex(c => c.Index);
builder.Entity<News>().HasOne<NewsCategory>().WithMany().HasForeignKey(c => c.CategoryId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Conversation>().HasIndex(c => c.Index);
builder.Entity<Message>().HasIndex(c => c.Index);
builder.Entity<Message>().HasOne<Conversation>().WithMany().HasForeignKey(c => c.ConversationId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<MessageCopy>().HasIndex(c => c.Index);
builder.Entity<MessageCopy>().HasOne<Conversation>().WithMany().HasForeignKey(c => c.ConversationId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<PublicWalkRequest>().HasIndex(c => c.Index);
builder.Entity<PublicWalkRequest>().OwnsOne(p => p.PickupAddress);
builder.Entity<PublicWalkRequest>().Property(c => c.Price).HasColumnType("decimal(18,2)");
builder.Entity<PublicWalkResponse>().HasIndex(c => c.Index);
builder.Entity<PublicWalkResponse>().Property(c => c.Price).HasColumnType("decimal(18,2)");
builder.Entity<PublicWalkRequestNotification>().OwnsOne(p => p.PickupAddress);
builder.Entity<Walk>().HasIndex(c => c.Index);
builder.Entity<Walk>().OwnsOne(p => p.PickupAddress);
builder.Entity<Walk>().OwnsOne(p => p.ReturnAddress);
builder.Entity<Walk>().Property(c => c.Price).HasColumnType("decimal(18,2)");
builder.Entity<Walk>().Property(c => c.VoucherAmmount).HasColumnType("decimal(18,2)");
builder.Entity<WalkComplaint>().HasIndex(c => c.Index);
builder.Entity<WalkComplaint>().HasOne<Walk>().WithMany().HasForeignKey(c => c.WalkId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Rating>().HasIndex(c => c.Index);
builder.Entity<Rating>().Property(c => c.Points).HasColumnType("decimal(18,2)");
builder.Entity<Favourite>().HasIndex(c => c.Index);
builder.Entity<SystemMessage>().HasIndex(c => c.Index);
builder.Entity<Device>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<TransactionFee>().Property(c => c.Percent).HasColumnType("decimal(18,2)");
builder.Entity<TransactionFee>().Property(c => c.Fixed).HasColumnType("decimal(18,2)");
builder.Entity<GehGassiFee>().Property(c => c.Percent).HasColumnType("decimal(18,2)");
builder.Entity<GehGassiFee>().Property(c => c.Fixed).HasColumnType("decimal(18,2)");
builder.Entity<GehGassiFee>().Property(c => c.StartAmmount).HasColumnType("decimal(18,2)");
builder.Entity<IdentityDocument>().HasIndex(c => c.Index);
builder.Entity<IdentityDocument>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Payout>().HasIndex(c => c.Index);
builder.Entity<Payout>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Card>().HasIndex(c => c.Index);
builder.Entity<Card>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<CoinsAccount>().HasIndex(c => c.Index);
builder.Entity<CoinsAccount>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<CoinsAccount>().Property(c => c.Balance).HasColumnType("decimal(18,2)");
builder.Entity<CoinsTransaction>().HasOne<CoinsAccount>().WithMany().HasForeignKey(c => c.AccountId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<CoinsTransaction>().Property(c => c.Ammount).HasColumnType("decimal(18,2)");
builder.Entity<CoinsPerMonth>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<CoinsPerMonth>().Property(c => c.Balance).HasColumnType("decimal(18,2)");
builder.Entity<CoinsPerYear>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<CoinsPerYear>().Property(c => c.Balance).HasColumnType("decimal(18,2)");
builder.Entity<VoucherCampaign>().HasOne<Customer>().WithMany().HasForeignKey(c => c.CustomerId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<VoucherCampaign>().OwnsOne(p => p.Address);
builder.Entity<VoucherCampaign>().Property(c => c.Budget).HasColumnType("decimal(18,4)");
builder.Entity<VoucherCampaign>().Property(c => c.BudgetUsed).HasColumnType("decimal(18,4)");
builder.Entity<VoucherCampaign>().Property(c => c.VoucherAmmount).HasColumnType("decimal(18,4)");
builder.Entity<Voucher>().HasOne<VoucherCampaign>().WithMany().HasForeignKey(c => c.VoucherCampaignId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<Voucher>().Property(c => c.VoucherAmmount).HasColumnType("decimal(18,4)");
builder.Entity<VoucherUsage>().HasOne<Voucher>().WithMany().HasForeignKey(c => c.VoucherId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<VoucherUsage>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<VoucherUsage>().HasOne<Walk>().WithMany().HasForeignKey(c => c.WalkId).OnDelete(DeleteBehavior.ClientSetNull);
builder.Entity<VoucherUsage>().Property(c => c.VoucherAmmount).HasColumnType("decimal(18,4)");
builder.Entity<VoucherUsage>().Property(c => c.VoucherAmmountUsed).HasColumnType("decimal(18,4)");
builder.Entity<Subscription>().Property(c => c.Price).HasColumnType("decimal(18,4)");
builder.Entity<AppUserSubscription>().HasOne<AppUser>().WithMany().HasForeignKey(c => c.AppUserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<AppUserSubscription>().HasOne<Subscription>().WithMany().HasForeignKey(c => c.SubscriptionId).OnDelete(DeleteBehavior.Cascade);
//Views
builder.Entity<AuditWithNames>().HasNoKey().ToView("vw_AuditsWithNames");
builder.Entity<ApplicationUserWithNames>().HasNoKey().ToView("vw_ApplicationUsersWithNames");
builder.Entity<OrderPhysical>().HasNoKey().ToView("vw_OrdersPhysical");
builder.Entity<DogWalker>().HasNoKey().ToView("vw_DogWalkers");
builder.Entity<DogWalker>().Property(c => c.RatingStatistics_TotalPoints).HasColumnType("decimal(18,2)");
builder.Entity<DogWalker>().Property(c => c.RatingStatistics_AverageRating).HasColumnType("decimal(18,2)");
builder.Entity<DogWalker>().Property(c => c.RatingStatisticsWalker_TotalPoints).HasColumnType("decimal(18,2)");
builder.Entity<DogWalker>().Property(c => c.RatingStatisticsWalker_AverageRating).HasColumnType("decimal(18,2)");
builder.Entity<DogWalker>().Property(c => c.PriceWalk).HasColumnType("decimal(18,2)");
builder.Entity<DogWalker>().Property(c => c.PriceDay).HasColumnType("decimal(18,2)");
builder.Entity<DogWalker>().Property(c => c.PriceSitting).HasColumnType("decimal(18,2)");
builder.Entity<RatingWithNames>().HasNoKey().ToView("vw_RatingsWithNames");
builder.Entity<RatingWithNames>().Property(c => c.Points).HasColumnType("decimal(18,2)");
builder.Entity<AppUserReportWithNames>().HasNoKey().ToView("vw_AppUserReportsWithNames");
builder.Entity<ConversationWithNames>().HasNoKey().ToView("vw_ConversationsWithNames");
builder.Entity<CoinsPerMonthWithNames>().HasNoKey().ToView("vw_CoinsPerMonthWithNames");
builder.Entity<CoinsPerMonthWithNames>().Property(c => c.Balance).HasColumnType("decimal(18,2)");
builder.Entity<CoinsPerYearWithNames>().HasNoKey().ToView("vw_CoinsPerYearWithNames");
builder.Entity<CoinsPerYearWithNames>().Property(c => c.Balance).HasColumnType("decimal(18,2)");
//Stored Procedures
//Table-Value functions
builder.Entity<CustomerWithNames>().HasNoKey().ToView(null);
builder.Entity<CustomerWithNames>().HasNoKey().Property("CountryCode").HasColumnName("Address_CountryCode");
builder.Entity<CustomerWithNames>().Property(c => c.MarkupListing).HasColumnType("decimal(18,2)");
builder.Entity<CustomerWithNames>().Property(c => c.MarkupAdvertisement).HasColumnType("decimal(18,2)");
builder.Entity<CustomerWithNames>().Property(c => c.MarkupPin).HasColumnType("decimal(18,2)");
builder.Entity<CustomerWithNames>().Property(c => c.MarkupBanner).HasColumnType("decimal(18,2)");
builder.Entity<AdvertisementCategoryWithNames>().HasNoKey().ToView(null);
builder.Entity<ProductCategoryWithNames>().HasNoKey().ToView(null);
builder.Entity<ProductWithNames>().HasNoKey().ToView(null);
builder.Entity<ProductWithNames>().Property(c => c.AdditionalShippingCharge).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNames>().Property(c => c.Price).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNames>().Property(c => c.OldPrice).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNames>().Property(c => c.Price2).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNames>().Property(c => c.OldPrice2).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNames>().Property(c => c.Weight).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNames>().Property(c => c.Length).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNames>().Property(c => c.Width).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNames>().Property(c => c.Height).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNames>().Property(c => c.PinPercentPerKm).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNamesCountry>().HasNoKey().ToView(null);
builder.Entity<ProductWithNamesCountry>().Property(c => c.AdditionalShippingCharge).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.Price).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.OldPrice).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.Price2).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.OldPrice2).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.Weight).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.Length).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.Width).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.Height).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.PinPercentPerKm).HasColumnType("decimal(18,2)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.PriceCountry).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.OldPriceCountry).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.Price2Country).HasColumnType("decimal(18,4)");
builder.Entity<ProductWithNamesCountry>().Property(c => c.OldPrice2Country).HasColumnType("decimal(18,4)");
builder.Entity<TaxRateWithNames>().HasNoKey().ToView(null);
builder.Entity<TaxRateWithNames>().Property(c => c.Value).HasColumnType("decimal(18,2)");
builder.Entity<CartItemWithNames>().HasNoKey().ToView(null);
builder.Entity<CartItemWithNames>().Property(c => c.Price).HasColumnType("decimal(18,4)");
builder.Entity<CartItemWithNames>().Property(c => c.Price2).HasColumnType("decimal(18,4)");
builder.Entity<CartItemWithNames>().Property(c => c.PriceGross).HasColumnType("decimal(18,2)");
builder.Entity<CartItemWithNames>().Property(c => c.Price2Gross).HasColumnType("decimal(18,2)");
builder.Entity<CartItemWithNames>().Property(c => c.Total).HasColumnType("decimal(18,2)");
builder.Entity<CartItemWithNames>().Property(c => c.TotalGross).HasColumnType("decimal(18,2)");
builder.Entity<CartItemWithNames>().Property(c => c.TaxRate).HasColumnType("decimal(18,2)");
builder.Entity<CartItemWithNames>().Property(c => c.TaxRateValue).HasColumnType("decimal(18,2)");
builder.Entity<CartWithNames>().HasNoKey().ToView(null);
builder.Entity<CartWithNames>().Property(c => c.Total).HasColumnType("decimal(18,2)");
builder.Entity<CartWithNames>().Property(c => c.TotalGross).HasColumnType("decimal(18,2)");
builder.Entity<CartWithNames>().Property(c => c.Shipment).HasColumnType("decimal(18,2)");
builder.Entity<CartWithNames>().Property(c => c.ShipmentGross).HasColumnType("decimal(18,2)");
builder.Entity<BranchWithNames>().HasNoKey().ToView(null);
builder.Entity<ListingWithNames>().HasNoKey().ToView(null);
builder.Entity<AdvertisementWithNames>().HasNoKey().ToView(null);
builder.Entity<AdvertisementWithNames>().Property(c => c.Discount).HasColumnType("decimal(18,2)");
builder.Entity<BannerWithNames>().HasNoKey().ToView(null);
builder.Entity<BannerWithNames>().Property(c => c.Budget).HasColumnType("decimal(18,4)");
builder.Entity<BannerWithNames>().Property(c => c.BudgetUsed).HasColumnType("decimal(18,4)");
builder.Entity<BannerWithNames>().Property(c => c.PriceView).HasColumnType("decimal(18,4)");
builder.Entity<BannerWithNames>().Property(c => c.PriceClick).HasColumnType("decimal(18,4)");
builder.Entity<PinWithNames>().HasNoKey().ToView(null);
builder.Entity<DogRaceWithNames>().HasNoKey().ToView(null);
builder.Entity<DogWithNames>().HasNoKey().ToView(null);
builder.Entity<DogWithNames>().Property(c => c.RatingStatistics_AverageRating).HasColumnType("decimal(18,2)");
builder.Entity<DogWithNames>().Property(c => c.RatingStatistics_TotalPoints).HasColumnType("decimal(18,2)");
builder.Entity<NewsCategoryWithNames>().HasNoKey().ToView(null);
builder.Entity<NewsWithNames>().HasNoKey().ToView(null);
builder.Entity<PageWithNames>().HasNoKey().ToView(null);
builder.Entity<FaqWithNames>().HasNoKey().ToView(null);
builder.Entity<ConversationWithTarget>().HasNoKey().ToView(null);
builder.Entity<PublicWalkRequestWithNames>().HasNoKey().ToView(null);
builder.Entity<PublicWalkRequestWithNames>().Property(c => c.Price).HasColumnType("decimal(18,2)");
builder.Entity<PublicWalkRequestWithNamesAndResponseStatus>().HasNoKey().ToView(null);
builder.Entity<PublicWalkRequestWithNamesAndResponseStatus>().Property(c => c.Price).HasColumnType("decimal(18,2)");
builder.Entity<PublicWalkResponseWithNames>().HasNoKey().ToView(null);
builder.Entity<PublicWalkResponseWithNames>().Property(c => c.Price).HasColumnType("decimal(18,2)");
builder.Entity<WalkWithNames>().HasNoKey().ToView(null);
builder.Entity<WalkWithNames>().Property(c => c.Price).HasColumnType("decimal(18,2)");
builder.Entity<WalkWithNames>().Property(c => c.VoucherAmmount).HasColumnType("decimal(18,2)");
builder.Entity<WalkComplaintWithNames>().HasNoKey().ToView(null);
builder.Entity<WalkComplaintWithNames>().Property(c => c.WalkPrice).HasColumnType("decimal(18,2)");
builder.Entity<AppUserBlockWithNames>().HasNoKey().ToView(null);
builder.Entity<RatingWithNamesEx>().HasNoKey().ToView(null);
builder.Entity<RatingWithNamesEx>().Property(c => c.Points).HasColumnType("decimal(18,2)");
builder.Entity<AppVersionWithNames>().HasNoKey().ToView(null);
builder.Entity<VoucherCampaignWithNames>().HasNoKey().ToView(null);
builder.Entity<VoucherCampaignWithNames>().Property(c => c.Budget).HasColumnType("decimal(18,4)");
builder.Entity<VoucherCampaignWithNames>().Property(c => c.BudgetUsed).HasColumnType("decimal(18,4)");
builder.Entity<VoucherCampaignWithNames>().Property(c => c.VoucherAmmount).HasColumnType("decimal(18,4)");
builder.Entity<SubscriptionWithNames>().HasNoKey().ToView(null);
builder.Entity<SubscriptionWithNames>().Property(c => c.Price).HasColumnType("decimal(18,4)");
builder.Entity<AppUserSubscriptionWithNames>().HasNoKey().ToView(null);
builder.Entity<AppUserSubscriptionWithNames>().Property(c => c.SubscriptionPrice).HasColumnType("decimal(18,4)");
}
/// <summary>
/// Speichern der Änderungen mit Auditing (wenn aktiviert) und Benutzername
/// </summary>
/// <param name="userName">Benutzer der die Änderungen vorgenommen hat</param>
/// <param name="noAudit">Gibt an, dass kein Audit-Eintrag erstellt werden soll, auch wenn Audit aktiviert ist</param>
/// <returns>Anzahl betroffener Datensätze</returns>
public int SaveChanges(string userName, bool noAudit)
{
if (_auditOptions.IsEnabled && !noAudit)
{
var auditEntries = OnBeforeSaveChanges(userName);
var result = base.SaveChanges();
OnAfterSaveChanges(auditEntries, userName).GetAwaiter().GetResult();
return result;
}
return base.SaveChanges();
}
/// <summary>
/// Speichern der Änderungen mit Auditing (wenn aktiviert) und Benutzername
/// </summary>
/// <param name="userName">Benutzer der die Änderungen vorgenommen hat</param>
/// <param name="noAudit">Gibt an, dass kein Audit-Eintrag erstellt werden soll, auch wenn Audit aktiviert ist</param>
/// <returns>Anzahl betroffener Datensätze</returns>
public async Task<int> SaveChangesAsync(string userName, bool noAudit)
{
if (_auditOptions.IsEnabled && !noAudit)
{
var auditEntries = OnBeforeSaveChanges(userName);
var result = await base.SaveChangesAsync();
await OnAfterSaveChanges(auditEntries, userName);
return result;
}
return await base.SaveChangesAsync();
}
/// <summary>
/// Hilfsmethode die, wenn Auditing aktiviert ist, die Änderungen erfasst.
/// Wird so implementiert, da es Änderungne gibt die erst nach dem Speichern gültig werden
/// </summary>
/// <param name="userName">Benutzername</param>
/// <returns>Liste von audit-Einträgen</returns>
private List<AuditEntry> OnBeforeSaveChanges(string userName)
{
ChangeTracker.DetectChanges();
var auditEntries = new List<AuditEntry>();
foreach (var entry in ChangeTracker.Entries())
{
if (entry.Entity is IAuditable == false || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged)
continue;
var entity = entry.Entity as IAuditable;
var auditEntry = new AuditEntry(entry);
auditEntry.Action = entry.State switch
{
EntityState.Added => AuditAction.Create,
EntityState.Modified => AuditAction.Edit,
EntityState.Deleted => AuditAction.Delete,
_ => auditEntry.Action
};
//Reagieren auf die individuellen Einstellungen der Entitäten - was soll geloggt werden
switch (auditEntry.Action)
{
case AuditAction.Create when !entity.Options().HasFlag(AuditableOptions.Create):
case AuditAction.Edit when !entity.Options().HasFlag(AuditableOptions.Edit):
case AuditAction.Delete when !entity.Options().HasFlag(AuditableOptions.Delete):
continue;
}
auditEntries.Add(auditEntry);
HandleProperties(entry, auditEntry);
foreach (var entryReference in entry.References)
{
var internalEntry = entryReference.TargetEntry;
HandleProperties(internalEntry, auditEntry, entryReference.Metadata.Name);
}
}
// Save audit entities that have all the modifications
foreach (var auditEntry in auditEntries.Where(_ => !_.HasTemporaryProperties))
{
Audits.Add(auditEntry.ToAudit(userName));
}
// keep a list of entries where the value of some properties are unknown at this step
return auditEntries.Where(_ => _.HasTemporaryProperties).ToList();
}
/// <summary>
/// Erfassen der einzelnen Properties für den AuditEntry
/// </summary>
/// <param name="entry">EntityEntry</param>
/// <param name="auditEntry">AuditEntry</param>
/// <param name="prefix">Optional: Prefix wenn nested</param>
private static void HandleProperties(EntityEntry entry, AuditEntry auditEntry, string prefix = "")
{
if(entry == null || !entry.Properties.Any())
return;
foreach (var property in entry.Properties)
{
if (property.IsTemporary)
{
// value will be generated by the database, get the value after saving
auditEntry.TemporaryProperties.Add(property);
continue;
}
var propertyName = property.Metadata.Name;
if (!string.IsNullOrWhiteSpace(prefix))
propertyName = $"{prefix}.{propertyName}";
if (string.IsNullOrWhiteSpace(prefix))
{
//Den Key nicht doppelt erfassen wenn es sich um eine nested property handelt
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
}
switch (entry.State)
{
case EntityState.Added:
auditEntry.NewValues[propertyName] = property.CurrentValue;
//auditEntry.Action = 1;
break;
case EntityState.Deleted:
auditEntry.OldValues[propertyName] = property.OriginalValue;
//auditEntry.Action = 3;
break;
case EntityState.Modified:
if (property.IsModified)
{
auditEntry.OldValues[propertyName] = property.OriginalValue;
auditEntry.NewValues[propertyName] = property.CurrentValue;
//auditEntry.Action = 2;
if (propertyName.ToLowerInvariant() == "deleted")
{
if (auditEntry.NewValues[propertyName] is bool)
{
var deleted = (bool)auditEntry.NewValues[propertyName];
if (deleted)
auditEntry.Action = AuditAction.DeleteSoft;
}
}
}
break;
}
}
}
/// <summary>
/// Behandelt von noch nicht gespeicherten Audit-Objekten.
/// Hier wegen dem Umstand, dass nicht alle DB-Änderungen vor dem Speichern verfügbar ist
/// </summary>
/// <param name="auditEntries"></param>
/// <param name="userName"></param>
/// <returns></returns>
private async Task OnAfterSaveChanges(List<AuditEntry> auditEntries, string userName)
{
if (auditEntries == null || auditEntries.Count == 0)
return;
foreach (var auditEntry in auditEntries)
{
// Get the final value of the temporary properties
foreach (var prop in auditEntry.TemporaryProperties)
{
if (prop.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[prop.Metadata.Name] = prop.CurrentValue;
}
else
{
auditEntry.NewValues[prop.Metadata.Name] = prop.CurrentValue;
}
}
// Save the Audit entry
Audits.Add(auditEntry.ToAudit(userName));
}
await SaveChangesAsync();
}
}
/// <summary>
/// Hilfsklasse für das Erfassen von Audits
/// </summary>
internal class AuditEntry
{
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="entry">Entity Entry</param>
public AuditEntry(EntityEntry entry)
{
Entry = entry;
}
public EntityEntry Entry { get; }
/// <summary>
/// Durchgeführte Aktion
/// </summary>
public AuditAction Action { get; set; }
public Dictionary<string, object> KeyValues { get; } = new Dictionary<string, object>();
public Dictionary<string, object> OldValues { get; } = new Dictionary<string, object>();
public Dictionary<string, object> NewValues { get; } = new Dictionary<string, object>();
public List<PropertyEntry> TemporaryProperties { get; } = new List<PropertyEntry>();
public bool HasTemporaryProperties => TemporaryProperties.Any();
/// <summary>
/// Konvertiert den Eintrag in die Audit-Klasse zum Speichern
/// </summary>
/// <param name="userName">Benutzername</param>
/// <returns></returns>
public Audit ToAudit(string userName)
{
var jsonOptions = new JsonSerializerSettings()
{
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
jsonOptions.Converters.Add(new NetTopologySuite.IO.Converters.GeometryConverter());
var audit = new Audit
{
Key = ((IAuditable)this.Entry.Entity).AuditKey(),
Table = ((IAuditable)this.Entry.Entity).AuditTable(),
UserName = userName,
Action = this.Action,
DateTime = DateTimeOffset.UtcNow,
KeyValues = KeyValues.Count == 0 ? null : JsonConvert.SerializeObject(KeyValues, jsonOptions),
OldValues = OldValues.Count == 0 ? null : JsonConvert.SerializeObject(OldValues, jsonOptions),
NewValues = NewValues.Count == 0 ? null : JsonConvert.SerializeObject(NewValues, jsonOptions)
};
return audit;
}
}
}