Merge branch 'newgen' of https://github.com/ceee/zero into newgen

This commit is contained in:
2025-10-07 11:56:14 +02:00
5 changed files with 107 additions and 122 deletions
+27 -121
View File
@@ -4,6 +4,7 @@ using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using ServiceStack.OrmLite;
using ServiceStack.OrmLite.Dapper;
using zero.Extensions;
using zero.Models;
using zero.Utils;
@@ -67,125 +68,30 @@ public partial class DbOperations : IDbOperations
}
// /// <inheritdoc />
// public virtual async Task<bool> Any<T>(Func<IRavenQueryable<T>, IQueryable<T>> querySelector = default) where T : ZeroIdEntity, new()
// {
// querySelector ??= x => x;
// return await querySelector(Session.Query<T>()).AnyAsync();
// }
//
//
// /// <inheritdoc />
// public virtual async Task<Paged<T>> Load<T>(int pageNumber, int pageSize, Func<IRavenQueryable<T>, IQueryable<T>> querySelector = default) where T : ZeroIdEntity, new()
// {
// IRavenQueryable<T> queryable = Session.Query<T>().Statistics(out QueryStatistics statistics);
// querySelector ??= x => x;
//
// List<T> result = await querySelector(queryable).Paging(pageNumber, pageSize).ToListAsync();
// return new Paged<T>(result, statistics.TotalResults, pageNumber, pageSize);
// }
//
//
// /// <inheritdoc />
// public virtual async Task<Paged<T>> Load<T, TIndex>(int pageNumber, int pageSize, Func<IRavenQueryable<T>, IQueryable<T>> querySelector = default)
// where T : ZeroIdEntity, new()
// where TIndex : AbstractCommonApiForIndexes, new()
// {
// IRavenQueryable<T> queryable = Session.Query<T, TIndex>().Statistics(out QueryStatistics statistics);
// querySelector ??= x => x;
//
// List<T> result = await querySelector(queryable).Paging(pageNumber, pageSize).ToListAsync();
// return new Paged<T>(result, statistics.TotalResults, pageNumber, pageSize);
// }
//
//
// /// <inheritdoc />
// public virtual async Task<List<T>> Load<T>(Func<IRavenQueryable<T>, IQueryable<T>> querySelector) where T : ZeroIdEntity, new()
// {
// IRavenQueryable<T> queryable = Session.Query<T>();
// querySelector ??= x => x;
//
// return await querySelector(queryable).ToListAsync();
// }
//
//
// /// <inheritdoc />
// public virtual async Task<List<T>> Load<T, TIndex>(Func<IRavenQueryable<T>, IQueryable<T>> querySelector)
// where T : ZeroIdEntity, new()
// where TIndex : AbstractCommonApiForIndexes, new()
// {
// IRavenQueryable<T> queryable = Session.Query<T, TIndex>();
// querySelector ??= x => x;
//
// return await querySelector(queryable).ToListAsync();
// }
//
//
// /// <inheritdoc />
// public virtual async Task<List<T>> Load<T>(Expression<Func<T, bool>> predicate) where T : ZeroIdEntity, new()
// {
// return await Session.Query<T>().Where(predicate).ToListAsync();
// }
//
//
// /// <inheritdoc />
// public virtual async Task<List<T>> Load<T, TIndex>(Expression<Func<T, bool>> predicate)
// where T : ZeroIdEntity, new()
// where TIndex : AbstractCommonApiForIndexes, new()
// {
// return await Session.Query<T, TIndex>().Where(predicate).ToListAsync();
// }
//
//
// /// <inheritdoc />
// public virtual async Task<Paged<TProjection>> Load<T, TIndex, TProjection>(int pageNumber, int pageSize, Func<IRavenQueryable<T>, IQueryable<T>> querySelector = default)
// where T : ZeroIdEntity, new()
// where TProjection : ZeroIdEntity, new()
// where TIndex : AbstractCommonApiForIndexes, new()
// {
// IRavenQueryable<T> queryable = Session.Query<T, TIndex>().Statistics(out QueryStatistics statistics);
// querySelector ??= x => x;
//
// List<TProjection> result = await querySelector(queryable).ProjectInto<TProjection>().Paging(pageNumber, pageSize).ToListAsync();
// return new Paged<TProjection>(result, statistics.TotalResults, pageNumber, pageSize);
// }
//
//
// /// <inheritdoc />
// public virtual async Task<List<T>> LoadAll<T>() where T : ZeroIdEntity, new()
// {
// List<T> items = new();
//
// await foreach (T item in Stream<T>(null))
// {
// items.Add(item);
// }
//
// return items;
// }
//
//
// /// <inheritdoc />
// public virtual async IAsyncEnumerable<T> Stream<T>(Func<IRavenQueryable<T>, IQueryable<T>> expression) where T : ZeroIdEntity, new()
// {
// IRavenQueryable<T> query = Session.Query<T>();
// IQueryable<T> queryable = query;
//
// if (expression != null)
// {
// queryable = expression(query);
// }
//
// var stream = await Session.Advanced.StreamAsync(queryable);
//
// while (await stream.MoveNextAsync())
// {
// if (WhenActive(stream.Current.Document) == default)
// {
// continue;
// }
//
// yield return stream.Current.Document;
// }
// }
/// <inheritdoc />
public virtual async Task<bool> Any<T>(Expression<Func<T, bool>> querySelector = null) where T : ZeroIdEntity, new()
{
return await Db.ExistsAsync(querySelector ?? (x => true));
}
/// <inheritdoc />
public virtual async Task<List<T>> Load<T>(Expression<Func<T, bool>> querySelector) where T : ZeroIdEntity, new()
{
return await Db.SelectAsync(querySelector ?? (x => true));
}
/// <inheritdoc />
public virtual async Task<List<T>> LoadBySql<T>(Func<SqlExpression<T>, SqlExpression<T>> querySelector) where T : ZeroIdEntity, new()
{
return await Db.SelectAsync(querySelector(Db.From<T>()));
}
/// <inheritdoc />
public virtual async Task<List<T>> LoadAll<T>() where T : ZeroIdEntity, new()
{
return await Db.SelectAsync<T>(x => true);
}
}
+21
View File
@@ -151,6 +151,27 @@ public interface IDbOperations
/// </summary>
Task<List<T>> LoadAsList<T>(IEnumerable<string> ids) where T : ZeroIdEntity, new();
/// <summary>
/// Check if any items exist in this collection (with optional query)
/// </summary>
Task<bool> Any<T>(Expression<Func<T, bool>> querySelector = null) where T : ZeroIdEntity, new();
/// <summary>
/// Get entities by query
/// </summary>
Task<List<T>> Load<T>(Expression<Func<T, bool>> querySelector) where T : ZeroIdEntity, new();
/// <summary>
/// Get entities by sql query
/// </summary>
Task<List<T>> LoadBySql<T>(Func<SqlExpression<T>, SqlExpression<T>> querySelector) where T : ZeroIdEntity, new();
/// <summary>
/// Get all entities from this collection.
/// Warning: Don't use this method for large collections. Stream the results instead.
/// </summary>
Task<List<T>> LoadAll<T>() where T : ZeroIdEntity, new();
/// <summary>
/// Creates an entity with an optional validator
/// </summary>
@@ -0,0 +1,37 @@
namespace zero.Localization;
public class FluentValidationGermanLanguage
{
public static readonly Dictionary<string, string> Translations = new()
{
{ "EmailValidator", "Keine gültige E-Mail-Adresse" },
{ "GreaterThanOrEqualValidator", "Der Wert muss grösser oder gleich '{ComparisonValue}' sein." },
{ "GreaterThanValidator", "Der Wert muss grösser sein als '{ComparisonValue}'." },
{ "LengthValidator", "Die Länge muss zwischen {MinLength} und {MaxLength} Zeichen liegen. Es wurden {TotalLength} Zeichen eingetragen." },
{ "MinimumLengthValidator", "Die Länge muss größer oder gleich {MinLength} sein. Sie haben {TotalLength} Zeichen eingegeben." },
{ "MaximumLengthValidator", "Die Länge muss kleiner oder gleich {MaxLength} sein. Sie haben {TotalLength} Zeichen eingegeben." },
{ "LessThanOrEqualValidator", "Der Wert muss kleiner oder gleich '{ComparisonValue}' sein." },
{ "LessThanValidator", "Der Wert muss kleiner sein als '{ComparisonValue}'." },
{ "NotEmptyValidator", "Dieses Feld darf nicht leer sein." },
{ "NotEqualValidator", "Dieser Wert darf nicht '{ComparisonValue}' sein." },
{ "NotNullValidator", "Dieses Feld darf nicht leer sein." },
{ "PredicateValidator", "Der Wert entspricht nicht der festgelegten Bedingung." },
{ "AsyncPredicateValidator", "Der Wert entspricht nicht der festgelegten Bedingung." },
{ "RegularExpressionValidator", "Dieses Feld weist ein ungültiges Format auf." },
{ "EqualValidator", "Der Wert muss gleich '{ComparisonValue}' sein." },
{ "ExactLengthValidator", "Dieses Feld muss genau {MaxLength} lang sein. Es wurden {TotalLength} eingegeben." },
{ "ExclusiveBetweenValidator", "Der Wert muss zwischen {From} und {To} sein (exklusiv). Es wurde {PropertyValue} eingegeben." },
{ "InclusiveBetweenValidator", "Der Wert muss zwischen {From} and {To} sein. Es wurde {PropertyValue} eingegeben." },
{ "CreditCardValidator", "Keine gültige Kreditkartennummer." },
{ "ScalePrecisionValidator", "Das Feld darf insgesamt nicht mehr als {ExpectedPrecision} Ziffern enthalten, mit Berücksichtigung von {ExpectedScale} Dezimalstellen. Es wurden {Digits} Ziffern und {ActualScale} Dezimalstellen gefunden." },
{ "EmptyValidator", "Dieses Feld sollte leer sein." },
{ "NullValidator", "Dieses Feld sollte leer sein." },
{ "EnumValidator", "Dieses Feld hat einen Wertebereich, der '{PropertyValue}' nicht enthält." },
// Additional fallback messages used by clientside validation integration.
{ "Length_Simple", "Die Länge muss zwischen {MinLength} und {MaxLength} Zeichen liegen." },
{ "MinimumLength_Simple", "Die Länge muss größer oder gleich {MinLength} sein." },
{ "MaximumLength_Simple", "Die Länge muss kleiner oder gleich {MaxLength} sein." },
{ "ExactLength_Simple", "Dieses Feld muss genau {MaxLength} lang sein." },
{ "InclusiveBetween_Simple", "Der Wert muss zwischen {From} and {To} sein." }
};
}
@@ -0,0 +1,18 @@
using FluentValidation.Resources;
namespace zero.Localization;
public static class LanguageManagerExtensions
{
public static ILanguageManager AddGermanOverrides(this ILanguageManager manager)
{
if (manager is LanguageManager languageManager)
{
foreach (var kvp in FluentValidationGermanLanguage.Translations)
{
languageManager.AddTranslation("de", kvp.Key, kvp.Value);
}
}
return manager;
}
}
+4 -1
View File
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc.Localization;
using FluentValidation;
using Microsoft.AspNetCore.Mvc.Localization;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -12,6 +13,8 @@ internal class ZeroLocalizationModule : ZeroModule
{
// hint: think about using https://github.com/nuages-io/nuages-localization
ValidatorOptions.Global.LanguageManager.AddGermanOverrides();
services.AddScoped<ICultureResolver, CultureResolver>();
services.AddScoped<ICultureService, CultureService>();
services.AddScoped<ILocalizer, ConfigurationLocalizer>();