Skip to content

Commit 1f09337

Browse files
committed
Cron Expression final
1 parent f605a95 commit 1f09337

40 files changed

Lines changed: 535 additions & 327 deletions

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,4 @@ Kopie von*
218218

219219
src/SmartStoreNET.Packager.sln
220220
Log.txt
221-
src/.vs/
221+
.vs/

src/Libraries/SmartStore.Core/Data/IDbContext.cs

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
32
using System.Data;
43
using System.Data.Common;
54
using System.Data.Entity;
65
using System.Threading.Tasks;
7-
using SmartStore.Core;
86

97
namespace SmartStore.Core.Data
108
{
@@ -83,36 +81,37 @@ IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params ob
8381
/// <typeparam name="TEntity">Type of entity</typeparam>
8482
/// <param name="entity">The entity instance to attach</param>
8583
/// <returns><c>true</c> when the entity is attched already, <c>false</c> otherwise</returns>
86-
bool IsAttached<TEntity>(TEntity entity) where TEntity : BaseEntity, new();
84+
bool IsAttached<TEntity>(TEntity entity) where TEntity : BaseEntity;
8785

8886
/// <summary>
8987
/// Detaches an entity from the current object context if it's attached
9088
/// </summary>
9189
/// <typeparam name="TEntity">Type of entity</typeparam>
9290
/// <param name="entity">The entity instance to detach</param>
93-
void DetachEntity<TEntity>(TEntity entity) where TEntity : BaseEntity, new();
91+
void DetachEntity<TEntity>(TEntity entity) where TEntity : BaseEntity;
9492

9593
/// <summary>
9694
/// Detaches all entities of type <c>TEntity</c> from the current object context
9795
/// </summary>
96+
/// <param name="unchangedEntitiesOnly">When <c>true</c>, only entities in unchanged state get detached.</param>
9897
/// <returns>The count of detached entities</returns>
99-
int DetachEntities<TEntity>() where TEntity : class;
98+
int DetachEntities<TEntity>(bool unchangedEntitiesOnly = true) where TEntity : class;
10099

101100
/// <summary>
102101
/// Change the state of an entity object
103102
/// </summary>
104103
/// <typeparam name="TEntity">Type of entity</typeparam>
105104
/// <param name="entity">The entity instance</param>
106105
/// <param name="newState">The new state</param>
107-
void ChangeState<TEntity>(TEntity entity, System.Data.Entity.EntityState newState) where TEntity : BaseEntity, new();
106+
void ChangeState<TEntity>(TEntity entity, System.Data.Entity.EntityState newState) where TEntity : BaseEntity;
108107

109108
/// <summary>
110109
/// Reloads the entity from the database overwriting any property values with values from the database.
111110
/// The entity will be in the Unchanged state after calling this method.
112111
/// </summary>
113112
/// <typeparam name="TEntity">Type of entity</typeparam>
114113
/// <param name="entity">The entity instance</param>
115-
void ReloadEntity<TEntity>(TEntity entity) where TEntity : BaseEntity, new();
114+
void ReloadEntity<TEntity>(TEntity entity) where TEntity : BaseEntity;
116115

117116
/// <summary>
118117
/// Begins a transaction on the underlying store connection using the specified isolation level
@@ -128,33 +127,4 @@ IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params ob
128127
void UseTransaction(DbTransaction transaction);
129128
}
130129

131-
public static class IDbContextExtensions
132-
{
133-
134-
public static int DetachAll(this IDbContext ctx)
135-
{
136-
return ctx.DetachEntities<BaseEntity>();
137-
}
138-
139-
/// <summary>
140-
/// Changes the object state to unchanged
141-
/// </summary>
142-
/// <typeparam name="TEntity">Type of entity</typeparam>
143-
/// <param name="entity">The entity instance</param>
144-
/// <returns>true on success, false on failure</returns>
145-
public static bool SetToUnchanged<TEntity>(this IDbContext ctx, TEntity entity) where TEntity : BaseEntity, new()
146-
{
147-
try
148-
{
149-
ctx.ChangeState<TEntity>(entity, System.Data.Entity.EntityState.Unchanged);
150-
return true;
151-
}
152-
catch (Exception ex)
153-
{
154-
ex.Dump();
155-
return false;
156-
}
157-
}
158-
159-
}
160130
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using SmartStore.Core;
4+
using SmartStore.Core.Data;
5+
6+
namespace SmartStore
7+
{
8+
public static class IDbContextExtensions
9+
{
10+
11+
/// <summary>
12+
/// Detaches all entities from the current object context
13+
/// </summary>
14+
/// <param name="unchangedEntitiesOnly">When <c>true</c>, only entities in unchanged state get detached.</param>
15+
/// <returns>The count of detached entities</returns>
16+
public static int DetachAll(this IDbContext ctx, bool unchangedEntitiesOnly = true)
17+
{
18+
return ctx.DetachEntities<BaseEntity>(unchangedEntitiesOnly);
19+
}
20+
21+
public static void DetachEntities<TEntity>(this IDbContext ctx, IEnumerable<TEntity> entities) where TEntity : BaseEntity
22+
{
23+
Guard.ArgumentNotNull(() => ctx);
24+
25+
entities.Each(x => ctx.DetachEntity(x));
26+
}
27+
28+
/// <summary>
29+
/// Changes the object state to unchanged
30+
/// </summary>
31+
/// <typeparam name="TEntity">Type of entity</typeparam>
32+
/// <param name="entity">The entity instance</param>
33+
/// <returns>true on success, false on failure</returns>
34+
public static bool SetToUnchanged<TEntity>(this IDbContext ctx, TEntity entity) where TEntity : BaseEntity
35+
{
36+
try
37+
{
38+
ctx.ChangeState<TEntity>(entity, System.Data.Entity.EntityState.Unchanged);
39+
return true;
40+
}
41+
catch (Exception ex)
42+
{
43+
ex.Dump();
44+
return false;
45+
}
46+
}
47+
48+
}
49+
}

src/Libraries/SmartStore.Core/Data/IQueryableExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
using System.Linq;
44
using System.Data.Entity;
55
using System.Linq.Expressions;
6+
using SmartStore.Core;
67

7-
namespace SmartStore.Core.Data
8+
namespace SmartStore
89
{
910
public static class IQueryableExtensions
1011
{

src/Libraries/SmartStore.Core/Data/IRepository.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ public partial interface IRepository<T> where T : BaseEntity
3939
/// <returns>The resolved entity</returns>
4040
T GetById(object id);
4141

42+
/// <summary>
43+
/// Attaches an entity to the context
44+
/// </summary>
45+
/// <param name="entity">The entity to attach</param>
46+
/// <returns>The entity</returns>
47+
T Attach(T entity);
48+
4249
/// <summary>
4350
/// Marks the entity instance to be saved to the store.
4451
/// </summary>

src/Libraries/SmartStore.Core/Data/RepositoryExtensions.cs

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,40 @@ public static IEnumerable<T> GetMany<T>(this IRepository<T> rs, IEnumerable<int>
4242
}
4343
}
4444

45-
public static void Delete<T>(this IRepository<T> rs, object id) where T : BaseEntity
45+
public static void Delete<T>(this IRepository<T> rs, int id) where T : BaseEntity
4646
{
47-
T entityToDelete = rs.GetById(id);
48-
if (entityToDelete != null)
49-
{
50-
rs.Delete(entityToDelete);
51-
}
47+
Guard.ArgumentNotZero(id, "id");
48+
49+
// Perf: work with stub entity
50+
var entity = rs.Create();
51+
entity.Id = id;
52+
53+
rs.Attach(entity);
54+
rs.Context.ChangeState(entity, System.Data.Entity.EntityState.Deleted);
5255
}
5356

57+
public static void DeleteRange<T>(this IRepository<T> rs, IEnumerable<int> ids) where T : BaseEntity
58+
{
59+
Guard.ArgumentNotNull(() => ids);
60+
61+
ids.Each(id => rs.Delete(id));
62+
}
63+
5464
/// <summary>
5565
/// Truncates the table
5666
/// </summary>
5767
/// <typeparam name="T">Entity type</typeparam>
5868
/// <param name="rs">The repository</param>
5969
/// <param name="predicate">An optional filter</param>
70+
/// <param name="cascade">
71+
/// <c>false</c>: does not make any attempts to determine dependant entities, just deletes ONLY them (faster).
72+
/// <c>true</c>: loads all entities into the context first and deletes them, along with their dependencies (slower).
73+
/// </param>
6074
/// <returns>The total number of affected entities</returns>
6175
/// <remarks>
6276
/// This method turns off auto detection, validation and hooking.
6377
/// </remarks>
64-
public static int DeleteAll<T>(this IRepository<T> rs, Expression<Func<T, bool>> predicate = null) where T : BaseEntity
78+
public static int DeleteAll<T>(this IRepository<T> rs, Expression<Func<T, bool>> predicate = null, bool cascade = false) where T : BaseEntity
6579
{
6680
var count = 0;
6781

@@ -73,11 +87,23 @@ public static int DeleteAll<T>(this IRepository<T> rs, Expression<Func<T, bool>>
7387
query = query.Where(predicate);
7488
}
7589

76-
var records = query.ToList();
77-
foreach (var chunk in records.Chunk(500))
90+
if (cascade)
91+
{
92+
var records = query.ToList();
93+
foreach (var chunk in records.Chunk(500))
94+
{
95+
rs.DeleteRange(chunk.ToList());
96+
count += rs.Context.SaveChanges();
97+
}
98+
}
99+
else
78100
{
79-
rs.DeleteRange(chunk.ToList());
80-
count += rs.Context.SaveChanges();
101+
var ids = query.Select(x => new { Id = x.Id }).ToList();
102+
foreach (var chunk in ids.Chunk(500))
103+
{
104+
rs.DeleteRange(chunk.Select(x => x.Id));
105+
count += rs.Context.SaveChanges();
106+
}
81107
}
82108
}
83109

src/Libraries/SmartStore.Core/Domain/Tasks/ScheduleTask.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
using System;
3+
using System.ComponentModel.DataAnnotations;
34
using System.ComponentModel.DataAnnotations.Schema;
45
using System.Diagnostics;
56

@@ -65,6 +66,12 @@ public class ScheduleTask : BaseEntity, ICloneable<ScheduleTask>
6566
/// </summary>
6667
public string ProgressMessage { get; set; }
6768

69+
/// <summary>
70+
/// Concurrency Token
71+
/// </summary>
72+
[Timestamp]
73+
public byte[] RowVersion { get; set; }
74+
6875
/// <summary>
6976
/// Gets a value indicating whether a task is running
7077
/// </summary>

src/Libraries/SmartStore.Core/SmartStore.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
<Compile Include="Collections\LazyMultimap.cs" />
156156
<Compile Include="Collections\QuerystringBuilder.cs" />
157157
<Compile Include="Collections\TopologicalSorter.cs" />
158+
<Compile Include="Data\IDbContextExtensions.cs" />
158159
<Compile Include="Data\ITransaction.cs" />
159160
<Compile Include="Domain\Catalog\PriceDisplayType.cs" />
160161
<Compile Include="Domain\DataExchange\SyncMapping.cs" />

src/Libraries/SmartStore.Data/Caching/EfCachingPolicy.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
using SmartStore.Core.Domain.Logging;
1515
using SmartStore.Core.Domain.Messages;
1616
using SmartStore.Core.Domain.Orders;
17+
using SmartStore.Core.Domain.Payments;
1718
using SmartStore.Core.Domain.Security;
19+
using SmartStore.Core.Domain.Shipping;
1820
using SmartStore.Core.Domain.Stores;
1921
using SmartStore.Core.Domain.Tax;
2022
using SmartStore.Core.Domain.Themes;
@@ -52,9 +54,11 @@ internal class EfCachingPolicy : CachingPolicy
5254
typeof(MeasureDimension).Name,
5355
typeof(MeasureWeight).Name,
5456
typeof(MessageTemplate).Name,
57+
typeof(PaymentMethod).Name,
5558
typeof(PermissionRecord).Name,
5659
typeof(ProductTemplate).Name,
5760
typeof(QuantityUnit).Name,
61+
typeof(ShippingMethod).Name,
5862
typeof(StateProvince).Name,
5963
typeof(Store).Name,
6064
typeof(StoreMapping).Name,

src/Libraries/SmartStore.Data/EfRepository.cs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ public virtual T GetById(object id)
6565
return this.Entities.Find(id);
6666
}
6767

68+
public virtual T Attach(T entity)
69+
{
70+
return this.Entities.Attach(entity);
71+
}
72+
6873
public virtual void Insert(T entity)
6974
{
7075
if (entity == null)
@@ -129,11 +134,7 @@ public virtual void Update(T entity)
129134
if (entity == null)
130135
throw new ArgumentNullException("entity");
131136

132-
if (InternalContext.Entry(entity).State == System.Data.Entity.EntityState.Detached)
133-
{
134-
this.Entities.Attach(entity);
135-
InternalContext.Entry(entity).State = System.Data.Entity.EntityState.Modified;
136-
}
137+
SetEntityStateToModifiedIfApplicable(entity);
137138

138139
if (this.AutoCommitEnabledInternal)
139140
{
@@ -148,11 +149,7 @@ public virtual void UpdateRange(IEnumerable<T> entities)
148149

149150
entities.Each(entity =>
150151
{
151-
if (InternalContext.Entry(entity).State == System.Data.Entity.EntityState.Detached)
152-
{
153-
this.Entities.Attach(entity);
154-
InternalContext.Entry(entity).State = System.Data.Entity.EntityState.Modified;
155-
}
152+
SetEntityStateToModifiedIfApplicable(entity);
156153
});
157154

158155
if (this.AutoCommitEnabledInternal)
@@ -161,6 +158,15 @@ public virtual void UpdateRange(IEnumerable<T> entities)
161158
}
162159
}
163160

161+
private void SetEntityStateToModifiedIfApplicable(T entity)
162+
{
163+
var entry = InternalContext.Entry(entity);
164+
if (entry.State == System.Data.Entity.EntityState.Detached || (this.AutoCommitEnabledInternal && !InternalContext.Configuration.AutoDetectChangesEnabled))
165+
{
166+
entry.State = System.Data.Entity.EntityState.Modified;
167+
}
168+
}
169+
164170
public virtual void Delete(T entity)
165171
{
166172
if (entity == null)
@@ -182,6 +188,14 @@ public virtual void DeleteRange(IEnumerable<T> entities)
182188
if (entities == null)
183189
throw new ArgumentNullException("entities");
184190

191+
entities.Each(entity =>
192+
{
193+
if (InternalContext.Entry(entity).State == System.Data.Entity.EntityState.Detached)
194+
{
195+
this.Entities.Attach(entity);
196+
}
197+
});
198+
185199
this.Entities.RemoveRange(entities);
186200

187201
if (this.AutoCommitEnabledInternal)

0 commit comments

Comments
 (0)