EF: AddOrUpdate

This commit is contained in:
pavelbannov 2019-12-17 16:01:59 +03:00
parent b2002a08db
commit f696558445
25 changed files with 236 additions and 55 deletions

View File

@ -418,7 +418,7 @@ client.GetPaymentUrls(null, products, !string.IsNullOrEmpty(affiliateId) ? affil
ButtonUrl = buttonUrl
};
CoreDbContext.Buttons.Add(efButton);
CoreDbContext.AddOrUpdate(r => r.Buttons, efButton);
CoreDbContext.SaveChanges();
}

View File

@ -28,6 +28,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using ASC.Core.Common.EF;
using ASC.Core.Tenants;
@ -160,7 +161,7 @@ namespace ASC.Core.Data
Tenant = r.Tenant
};
CoreDbContext.Acl.Add(record);
CoreDbContext.AddOrUpdate(r => r.Acl, record);
CoreDbContext.SaveChanges();
}
}

View File

@ -110,7 +110,7 @@ namespace ASC.Core.Data
Visible = quota.Visible
};
CoreDbContext.Quotas.Add(dbQuota);
CoreDbContext.AddOrUpdate(r => r.Quotas, dbQuota);
CoreDbContext.SaveChanges();
return quota;
@ -150,7 +150,7 @@ namespace ASC.Core.Data
LastModified = DateTime.UtcNow
};
CoreDbContext.QuotaRows.Add(dbQuotaRow);
CoreDbContext.AddOrUpdate(r => r.QuotaRows, dbQuotaRow);
CoreDbContext.SaveChanges();
tx.Commit();

View File

@ -166,7 +166,7 @@ namespace ASC.Core.Data
Data = data
};
WebstudioDbContext.WebstudioSettings.Add(s);
WebstudioDbContext.AddOrUpdate(r => r.WebstudioSettings, s);
}
WebstudioDbContext.SaveChanges();

View File

@ -28,6 +28,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using ASC.Core.Common.EF;
using ASC.Core.Tenants;
@ -113,7 +114,7 @@ namespace ASC.Core.Data
Tenant = s.Tenant
};
UserDbContext.Subscriptions.Add(subs);
UserDbContext.AddOrUpdate(r => r.Subscriptions, subs);
UserDbContext.SaveChanges();
}
@ -211,8 +212,10 @@ namespace ASC.Core.Data
Tenant = m.Tenant,
Sender = string.Join("|", m.Methods)
};
UserDbContext.SubscriptionMethods.Add(sm);
UserDbContext.AddOrUpdate(r => r.SubscriptionMethods, sm);
}
UserDbContext.SaveChanges();
tr.Commit();
}

View File

@ -420,7 +420,7 @@ namespace ASC.Core.Data
group.Tenant = tenant;
var dbGroup = FromGroupToDbGroup(group);
UserDbContext.Groups.Add(dbGroup);
UserDbContext.AddOrUpdate(r => r.Groups, dbGroup);
UserDbContext.SaveChanges();
return group;
@ -438,6 +438,7 @@ namespace ASC.Core.Data
user.UserName = user.UserName.Trim();
user.Email = user.Email.Trim();
using var tx = UserDbContext.Database.BeginTransaction();
var count = UserDbContext.Users.Where(r => r.UserName == user.UserName && r.Id != user.ID && !r.Removed).Count();
if (count != 0)
@ -445,8 +446,16 @@ namespace ASC.Core.Data
throw new ArgumentOutOfRangeException("Duplicate username.");
}
UserDbContext.Users.Add(FromUserInfoToUser(user));
count = UserDbContext.Users.Where(r => r.Email == user.Email && r.Id != user.ID && !r.Removed).Count();
if (count != 0)
{
throw new ArgumentOutOfRangeException("Duplicate email.");
}
UserDbContext.AddOrUpdate(r => r.Users, FromUserInfoToUser(user));
UserDbContext.SaveChanges();
tx.Commit();
return user;
}
@ -460,12 +469,15 @@ namespace ASC.Core.Data
using var tr = UserDbContext.Database.BeginTransaction();
UserDbContext.UserGroups.Add(FromUserGroupRefToUserGroup(r));
UserDbContext.AddOrUpdate(r => r.UserGroups, FromUserGroupRefToUserGroup(r));
var user = UserDbContext.Users.First(a => a.Tenant == tenant && a.Id == r.UserId);
var user = UserDbContext.Users.FirstOrDefault(a => a.Tenant == tenant && a.Id == r.UserId);
if (user != null)
{
user.LastModified = r.LastModified;
UserDbContext.SaveChanges();
}
UserDbContext.SaveChanges();
tr.Commit();
return r;
@ -476,9 +488,14 @@ namespace ASC.Core.Data
var h1 = !string.IsNullOrEmpty(password) ? Hasher.Base64Hash(password, HashAlg.SHA256) : null;
var h2 = !string.IsNullOrEmpty(password) ? Crypto.GetV(password, 1, true) : null;
var us = UserDbContext.UserSecurity.FirstOrDefault(r => r.UserId == id);
us.PwdHash = h1;
us.PwdHashSha512 = h2;
var us = new UserSecurity
{
UserId = id,
PwdHash = h1,
PwdHashSha512 = h2
};
UserDbContext.AddOrUpdate(r => r.UserSecurity, us);
UserDbContext.SaveChanges();
}
@ -502,6 +519,8 @@ namespace ASC.Core.Data
{
userPhoto.Photo = photo;
}
UserDbContext.AddOrUpdate(r => r.Photos, userPhoto);
}
else if (userPhoto != null)
{

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
@ -27,6 +28,28 @@ namespace ASC.Core.Common.EF
}
}
public static class BaseDbContextExtension
{
public static void AddOrUpdate<T, TContext>(this TContext b, Expression<Func<TContext, DbSet<T>>> expressionDbSet, T entity) where T : BaseEntity where TContext : BaseDbContext
{
var dbSet = expressionDbSet.Compile().Invoke(b);
var existingBlog = dbSet.Find(entity.GetKeys());
if (existingBlog == null)
{
dbSet.Add(entity);
}
else
{
b.Entry(existingBlog).CurrentValues.SetValues(entity);
}
}
}
public abstract class BaseEntity
{
internal abstract object[] GetKeys();
}
public class MultiRegionalDbContext<T> : IDisposable, IAsyncDisposable where T : BaseDbContext, new()
{
public MultiRegionalDbContext() { }

View File

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace ASC.Core.Common.EF
@ -19,16 +20,14 @@ namespace ASC.Core.Common.EF
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.AddAcl();
modelBuilder.Entity<DbButton>()
.HasKey(c => new { c.TariffId, c.PartnerId });
modelBuilder.Entity<DbQuotaRow>()
.HasKey(c => new { c.Tenant, c.Path });
modelBuilder
.AddAcl()
.AddDbButton()
.AddDbQuotaRow();
}
}
public static class CoreDbExtension
{
public static IServiceCollection AddCoreDbContextService(this IServiceCollection services)

View File

@ -22,15 +22,11 @@ namespace ASC.Core.Common.EF
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.AddAcl();
modelBuilder.Entity<Subscription>()
.HasKey(c => new { c.Tenant, c.Source, c.Action, c.Recipient, c.Object });
modelBuilder.Entity<DbSubscriptionMethod>()
.HasKey(c => new { c.Tenant, c.Source, c.Action, c.Recipient });
modelBuilder.AddUser();
modelBuilder
.AddAcl()
.AddSubscription()
.AddSubscriptionMethod()
.AddUser();
}
}

View File

@ -1,17 +1,23 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF.Model
{
[Table("account_links")]
public class AccountLinks : BaseDbContext
public class AccountLinks : BaseEntity
{
public string Id { get; set; }
public string UId { get; set; }
public string Provider { get; set; }
public string Profile { get; set; }
public DateTime Linked { get; set; }
internal override object[] GetKeys()
{
return new object[] { Id, UId };
}
}
public static class AccountLinksExtension

View File

@ -1,26 +1,35 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using ASC.Common.Security.Authorizing;
using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF
{
[Table("core_acl")]
public class Acl
public class Acl : BaseEntity
{
public int Tenant { get; set; }
public Guid Subject { get; set; }
public Guid Action { get; set; }
public string Object { get; set; }
public AceType AceType { get; set; }
internal override object[] GetKeys()
{
return new object[] { Tenant, Subject, Action, Object };
}
}
public static class AclExtension
{
public static void AddAcl(this ModelBuilder modelBuilder)
public static ModelBuilder AddAcl(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<Acl>()
.HasKey(c => new { c.Tenant, c.Subject, c.Action, c.Object });
return modelBuilder;
}
}
}

View File

@ -1,14 +1,32 @@
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF
{
[Table("core_subscriptionmethod")]
public class DbSubscriptionMethod
public class DbSubscriptionMethod : BaseEntity
{
public int Tenant { get; set; }
public string Source { get; set; }
public string Action { get; set; }
public string Recipient { get; set; }
public string Sender { get; set; }
internal override object[] GetKeys()
{
return new object[] { Tenant, Source, Action, Recipient };
}
}
public static class SubscriptionMethodExtension
{
public static ModelBuilder AddSubscriptionMethod(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<DbSubscriptionMethod>()
.HasKey(c => new { c.Tenant, c.Source, c.Action, c.Recipient });
return modelBuilder;
}
}
}

View File

@ -1,9 +1,11 @@
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF
{
[Table("core_subscription")]
public class Subscription
public class Subscription : BaseEntity
{
public int Tenant { get; set; }
public string Source { get; set; }
@ -11,5 +13,21 @@ namespace ASC.Core.Common.EF
public string Recipient { get; set; }
public string Object { get; set; }
public bool Unsubscribed { get; set; }
internal override object[] GetKeys()
{
return new object[] { Tenant, Source, Action, Recipient, Object };
}
}
public static class SubscriptionExtension
{
public static ModelBuilder AddSubscription(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<Subscription>()
.HasKey(c => new { c.Tenant, c.Source, c.Action, c.Recipient, c.Object });
return modelBuilder;
}
}
}

View File

@ -6,12 +6,17 @@ using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF.Model
{
[Table("webstudio_settings")]
public class DbWebstudioSettings
public class DbWebstudioSettings : BaseEntity
{
public int TenantId { get; set; }
public Guid Id { get; set; }
public Guid UserId { get; set; }
public string Data { get; set; }
internal override object[] GetKeys()
{
return new object[] { TenantId, Id, UserId };
}
}
public static class WebstudioSettingsExtension

View File

@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF.Model
{
[Table("feed_readed")]
public class FeedReaded
public class FeedReaded : BaseEntity
{
[Column("user_id")]
public Guid UserId { get; set; }
@ -15,6 +15,11 @@ namespace ASC.Core.Common.EF.Model
[Column("tenant_id")]
public int Tenant { get; set; }
internal override object[] GetKeys()
{
return new object[] { Tenant, UserId, Module };
}
}
public static class FeedReadedExtension

View File

@ -1,9 +1,11 @@
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF
{
[Table("tenants_buttons")]
public class DbButton
public class DbButton : BaseEntity
{
[Column("button_url")]
public string ButtonUrl { get; set; }
@ -13,5 +15,21 @@ namespace ASC.Core.Common.EF
[Column("partner_id")]
public string PartnerId { get; set; }
internal override object[] GetKeys()
{
return new object[] { TariffId, PartnerId };
}
}
public static class DbButtonExtension
{
public static ModelBuilder AddDbButton(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<DbButton>()
.HasKey(c => new { c.TariffId, c.PartnerId });
return modelBuilder;
}
}
}

View File

@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace ASC.Core.Common.EF
{
[Table("tenants_quota")]
public class DbQuota
public class DbQuota : BaseEntity
{
[Key]
public int Tenant { get; set; }
@ -27,5 +27,10 @@ namespace ASC.Core.Common.EF
public string AvangateId { get; set; }
public bool Visible { get; set; }
internal override object[] GetKeys()
{
return new object[] { Tenant };
}
}
}

View File

@ -1,10 +1,12 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF
{
[Table("tenants_quotarow")]
public class DbQuotaRow
public class DbQuotaRow : BaseEntity
{
public int Tenant { get; set; }
public string Path { get; set; }
@ -13,5 +15,21 @@ namespace ASC.Core.Common.EF
[Column("last_modified")]
public DateTime LastModified { get; set; }
internal override object[] GetKeys()
{
return new object[] { Tenant, Path };
}
}
public static class DbQuotaRowExtension
{
public static ModelBuilder AddDbQuotaRow(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<DbQuotaRow>()
.HasKey(c => new { c.Tenant, c.Path });
return modelBuilder;
}
}
}

View File

@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace ASC.Core.Common.EF
{
[Table("core_group")]
public class DbGroup
public class DbGroup : BaseEntity
{
public int Tenant { get; set; }
public Guid Id { get; set; }
@ -16,5 +16,10 @@ namespace ASC.Core.Common.EF
[Column("last_modified")]
public DateTime LastModified { get; set; }
internal override object[] GetKeys()
{
return new object[] { Id };
}
}
}

View File

@ -1,13 +1,15 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using ASC.Core.Users;
using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF
{
[Table("core_user")]
public class User
public class User : BaseEntity
{
public int Tenant { get; set; }
@ -68,6 +70,11 @@ namespace ASC.Core.Common.EF
public UserSecurity UserSecurity { get; set; }
public List<UserGroup> Groups { get; set; }
internal override object[] GetKeys()
{
return new object[] { Id };
}
}
public static class DbUserExtension

View File

@ -1,11 +1,12 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF
{
[Table("core_usergroup")]
public class UserGroup
public class UserGroup : BaseEntity
{
public int Tenant { get; set; }
@ -20,6 +21,11 @@ namespace ASC.Core.Common.EF
[Column("last_modified")]
public DateTime LastModified { get; set; }
internal override object[] GetKeys()
{
return new object[] { Tenant, UserId, GroupId, RefType };
}
}
public static class DbUserGroupExtension

View File

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace ASC.Core.Common.EF
{
[Table("core_userphoto")]
public class UserPhoto
public class UserPhoto : BaseEntity
{
public int Tenant { get; set; }
@ -13,5 +13,10 @@ namespace ASC.Core.Common.EF
public Guid UserId { get; set; }
public byte[] Photo { get; set; }
internal override object[] GetKeys()
{
return new object[] { UserId };
}
}
}

View File

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace ASC.Core.Common.EF
{
[Table("core_usersecurity")]
public class UserSecurity
public class UserSecurity : BaseEntity
{
public int Tenant { get; set; }
@ -15,5 +15,10 @@ namespace ASC.Core.Common.EF
public string PwdHash { get; set; }
public string PwdHashSha512 { get; set; }
internal override object[] GetKeys()
{
return new object[] { UserId };
}
}
}

View File

@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ASC.Common.Caching;
using ASC.Common.Data;
using ASC.Common.Utils;
@ -35,6 +36,7 @@ using ASC.Core.Common.EF.Context;
using ASC.Core.Common.EF.Model;
using ASC.FederatedLogin.Profile;
using ASC.Security.Cryptography;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@ -93,7 +95,7 @@ namespace ASC.FederatedLogin
options.AccountLinkerStorage = AccountLinkerStorage;
options.InstanceCrypto = InstanceCrypto;
options.Signature = Signature;
options.AccountLinkContext = DbContextManager;
options.AccountLinkContextManager = DbContextManager;
}
public void Configure(AccountLinker options)
@ -108,13 +110,21 @@ namespace ASC.FederatedLogin
public Signature Signature { get; set; }
public InstanceCrypto InstanceCrypto { get; set; }
public AccountLinkerStorage AccountLinkerStorage { get; set; }
public DbContextManager<AccountLinkContext> AccountLinkContext { get; set; }
public DbContextManager<AccountLinkContext> AccountLinkContextManager { get; set; }
public AccountLinkContext AccountLinkContext
{
get
{
return AccountLinkContextManager.Get(DbId);
}
}
public DbSet<AccountLinks> AccountLinks
{
get
{
return AccountLinkContext.Get(DbId).AccountLinks;
return AccountLinkContext.AccountLinks;
}
}
@ -168,8 +178,8 @@ namespace ASC.FederatedLogin
Linked = DateTime.UtcNow
};
AccountLinks.Add(accountLink);
AccountLinkContext.Get(DbId).SaveChanges();
AccountLinkContext.AddOrUpdate(r => r.AccountLinks, accountLink);
AccountLinkContext.SaveChanges();
AccountLinkerStorage.RemoveFromCache(obj);
}
@ -191,7 +201,7 @@ namespace ASC.FederatedLogin
public void RemoveProvider(string obj, string provider = null, string hashId = null)
{
using var tr = AccountLinkContext.Get(DbId).Database.BeginTransaction();
using var tr = AccountLinkContext.Database.BeginTransaction();
var accountLinkQuery = AccountLinks
.Where(r => r.Id == obj);

View File

@ -98,7 +98,7 @@ namespace ASC.Feed.Data
Tenant = tenant
};
FeedDbContext.FeedReaded.Add(feedReaded);
FeedDbContext.AddOrUpdate(r => r.FeedReaded, feedReaded);
FeedDbContext.SaveChanges();
}