seed/data Seeder GlobalSearch
This commit is contained in:
parent
3db82df964
commit
a1a76b1a95
6 changed files with 74 additions and 64 deletions
3
.github/instructions/lowcode.instructions.md
vendored
3
.github/instructions/lowcode.instructions.md
vendored
|
|
@ -3434,6 +3434,9 @@ Kurallar:
|
|||
- **Anahtar dosyada durur.** Insert varsayılanları anahtarı `@NEWID` ile üretir; `ListFormSeedDataApplier`
|
||||
dosyadaki anahtarı geri yazar, böylece aynı dosya birden çok kez uygulandığında kopya kayıt oluşmaz.
|
||||
Elle dosya yazarken anahtarı deterministik üret (ör. koddan türeyen GUID).
|
||||
- **Identity anahtarlı tablolarda satır anahtarsız yazılır.** `Id` alanı dosyada yoksa anahtar
|
||||
veritabanına bırakılır; satırın var olup olmadığı dosyadaki **tüm alan değerlerinin**
|
||||
(tenant kapsamı dahil) eşleşmesine bakılarak belirlenir.
|
||||
- **Uygulama yalnızca ekler:** anahtarı veritabanında bulunmayan satırlar `INSERT` edilir; var olan
|
||||
kayıt güncellenmez (her migrate'te ekrandaki güncel değerler dosyadaki eskisiyle ezilmesin diye)
|
||||
ve dosyada olmayan satır silinmez.
|
||||
|
|
|
|||
|
|
@ -1145,6 +1145,10 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
|||
SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.GlobalSearch)),
|
||||
KeyFieldName = "Id",
|
||||
KeyFieldDbSourceType = DbType.Int32,
|
||||
SeedFilePath = SeedPathResolver.GetDataFilePath(listFormName),
|
||||
SeedSyncInsert = false,
|
||||
SeedSyncUpdate = false,
|
||||
SeedSyncDelete = false,
|
||||
SortMode = GridOptions.SortModeSingle,
|
||||
FilterRowJson = DefaultFilterRowJson(),
|
||||
HeaderFilterJson = DefaultHeaderFilterJson(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
|
@ -138,7 +138,11 @@ public class ListFormSeedDataApplier(
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Satiri ekler; kayit eklendiyse <c>true</c>, ayni anahtarli kayit zaten varsa <c>false</c> doner.</summary>
|
||||
/// <summary>
|
||||
/// Satiri ekler; kayit eklendiyse <c>true</c>, ayni kayit zaten varsa <c>false</c> doner.
|
||||
/// Dosyada anahtar yoksa (identity kolonlu tablolar) satir diger alanlarinin tamami uzerinden
|
||||
/// eslesir ve anahtar veritabanina biraktirilir.
|
||||
/// </summary>
|
||||
private async Task<bool> ApplyRowAsync(
|
||||
ListForm listForm,
|
||||
List<ListFormField> fields,
|
||||
|
|
@ -154,37 +158,59 @@ public class ListFormSeedDataApplier(
|
|||
row.GetValueOrDefault(keyFieldName));
|
||||
|
||||
object[] keys = [keyValue];
|
||||
var hasKey = keyValue != null;
|
||||
|
||||
var insertParameters = BuildParameters(fields, row, keyFieldName, includeKey: hasKey);
|
||||
|
||||
// Var olan kayda dokunulmaz: veritabanindaki guncel deger, dosyadaki eski degerle ezilmemeli.
|
||||
if (await ExistsAsync(listForm, keyFieldName, keyValue, repository, connectionString))
|
||||
var match = hasKey
|
||||
? new Dictionary<string, object> { [keyFieldName] = keyValue }
|
||||
: new Dictionary<string, object>(insertParameters);
|
||||
|
||||
if (!hasKey && PlatformConsts.IsMultiTenant && listForm.IsTenant)
|
||||
{
|
||||
match["TenantId"] = currentTenant.Id;
|
||||
}
|
||||
|
||||
if (await ExistsAsync(listForm, match, repository, connectionString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var insertParameters = BuildParameters(fields, row, keyFieldName, includeKey: true);
|
||||
await MergeDefaultsAsync(listForm, fields, OperationEnum.Insert, keys, insertParameters);
|
||||
|
||||
// Insert varsayilanlari anahtari @NEWID ile uretir; dosyadaki anahtar korunmazsa ayni
|
||||
// dosya her uygulandiginda yeni kayit olusurdu.
|
||||
insertParameters[keyFieldName] = keyValue;
|
||||
if (hasKey)
|
||||
{
|
||||
// Insert varsayilanlari anahtari @NEWID ile uretir; dosyadaki anahtar korunmazsa ayni
|
||||
// dosya her uygulandiginda yeni kayit olusurdu.
|
||||
insertParameters[keyFieldName] = keyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Anahtari veritabani uretir; parametre listesinde kalirsa identity kolonuna
|
||||
// acik deger yazilmaya calisilir.
|
||||
insertParameters.Remove(keyFieldName);
|
||||
}
|
||||
|
||||
var insertSql = queryManager.GenerateQuery(listForm, fields, insertParameters, OperationEnum.Insert, dataSourceType, keys);
|
||||
await repository.ExecuteAsync(insertSql, connectionString, insertParameters);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Ayni anahtara sahip bir kayit hedef tabloda var mi.</summary>
|
||||
/// <summary>Verilen alan degerleriyle eslesen bir kayit hedef tabloda var mi.</summary>
|
||||
private static async Task<bool> ExistsAsync(
|
||||
ListForm listForm,
|
||||
string keyFieldName,
|
||||
object keyValue,
|
||||
Dictionary<string, object> match,
|
||||
IDynamicDataRepository repository,
|
||||
string connectionString)
|
||||
{
|
||||
var sql = $"SELECT COUNT(1) FROM \"{listForm.SelectCommand}\" WHERE \"{keyFieldName}\" = @{keyFieldName}";
|
||||
var parameters = new Dictionary<string, object> { [keyFieldName] = keyValue };
|
||||
var where = string.Join(
|
||||
" AND ",
|
||||
match.Select(a => a.Value == null ? $"\"{a.Key}\" IS NULL" : $"\"{a.Key}\" = @{a.Key}"));
|
||||
|
||||
return await repository.ExecuteScalarAsync<int>(sql, connectionString, parameters) > 0;
|
||||
var sql = $"SELECT COUNT(1) FROM \"{listForm.SelectCommand}\" WHERE {where}";
|
||||
|
||||
return await repository.ExecuteScalarAsync<int>(sql, connectionString, match) > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,4 @@
|
|||
{
|
||||
"GlobalSearch": [
|
||||
{
|
||||
"system": "Platform",
|
||||
"group": "Setting Definitions",
|
||||
"term": "Abp.Account.Captcha.EndPoint",
|
||||
"weight": "0.2",
|
||||
"url": "/admin/list/App.SettingDefinitions"
|
||||
},
|
||||
{
|
||||
"system": "Platform",
|
||||
"group": "Setting Definitions",
|
||||
"term": "Abp.Account.IsSelfRegistrationEnabled",
|
||||
"weight": "0.8",
|
||||
"url": "/admin/list/App.SettingDefinitions"
|
||||
},
|
||||
{
|
||||
"system": "Platform",
|
||||
"group": "Setting Definitions",
|
||||
"term": "Abp.Account.IsSelfRegistrationEnabled",
|
||||
"weight": "0.7",
|
||||
"url": "/admin/list/App.SettingDefinitions"
|
||||
}
|
||||
],
|
||||
"ForumCategories": [
|
||||
{
|
||||
"Name": "Genel Tartışma",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ namespace Sozsoft.Platform.Data.Seeds;
|
|||
public class TenantSeederDto
|
||||
{
|
||||
//Saas
|
||||
public List<GlobalSearchSeedDto> GlobalSearch { get; set; }
|
||||
public List<CustomEndpointSeedDto> CustomEndpoints { get; set; }
|
||||
public List<SequenceSeedDto> Sequences { get; set; }
|
||||
|
||||
|
|
@ -224,15 +223,6 @@ public class DepartmentSeedDto
|
|||
public string ParentName { get; set; }
|
||||
}
|
||||
|
||||
public class GlobalSearchSeedDto
|
||||
{
|
||||
public string System { get; set; }
|
||||
public string Group { get; set; }
|
||||
public string Term { get; set; }
|
||||
public string Weight { get; set; }
|
||||
public string Url { get; set; }
|
||||
}
|
||||
|
||||
public class UomCategorySeedDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
|
@ -430,7 +420,6 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
{
|
||||
private readonly ILookupNormalizer _lookupNormalizer;
|
||||
private readonly IRepository<Branch, Guid> _branchRepository;
|
||||
private readonly IRepository<GlobalSearch, int> _globalSearch;
|
||||
private readonly IRepository<CustomEndpoint, Guid> _customEndpointRepository;
|
||||
private readonly IRepository<ReportCategory, Guid> _reportCategoriesRepository;
|
||||
private readonly IRepository<ReportTemplate, Guid> _reportTemplatesRepository;
|
||||
|
|
@ -471,7 +460,6 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
ILookupNormalizer lookupNormalizer,
|
||||
IIdentityUserRepository repositoryUser,
|
||||
IRepository<Branch, Guid> branchRepository,
|
||||
IRepository<GlobalSearch, int> globalSearch,
|
||||
IRepository<UomCategory, string> uomCategoryRepository,
|
||||
IRepository<Uom, string> uomRepository,
|
||||
IRepository<SkillType, string> skillTypeRepository,
|
||||
|
|
@ -510,7 +498,6 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
_lookupNormalizer = lookupNormalizer;
|
||||
_repositoryUser = repositoryUser;
|
||||
_branchRepository = branchRepository;
|
||||
_globalSearch = globalSearch;
|
||||
_uomCategoryRepository = uomCategoryRepository;
|
||||
_uomRepository = uomRepository;
|
||||
_skillTypeRepository = skillTypeRepository;
|
||||
|
|
@ -559,21 +546,6 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
|
||||
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
|
||||
foreach (var item in items.GlobalSearch)
|
||||
{
|
||||
if (!await _globalSearch.AnyAsync(x => x.System == item.System && x.Group == item.Group && x.Term == item.Term))
|
||||
{
|
||||
await _globalSearch.InsertAsync(new GlobalSearch
|
||||
{
|
||||
System = item.System,
|
||||
Group = item.Group,
|
||||
Term = item.Term,
|
||||
Weight = item.Weight,
|
||||
Url = item.Url
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.UomCategories)
|
||||
{
|
||||
var exists = await _uomCategoryRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
|
|
|||
28
configs/seeds/host/data/App.Definitions.GlobalSearch.json
Normal file
28
configs/seeds/host/data/App.Definitions.GlobalSearch.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"ListFormCode": "App.Definitions.GlobalSearch",
|
||||
"KeyFieldName": "Id",
|
||||
"GeneratedAt": "2026-09-04T00:00:00Z",
|
||||
"Rows": [
|
||||
{
|
||||
"System": "Platform",
|
||||
"Group": "Setting Definitions",
|
||||
"Term": "Abp.Account.Captcha.EndPoint",
|
||||
"Url": "/admin/list/App.SettingDefinitions",
|
||||
"Weight": "0.2"
|
||||
},
|
||||
{
|
||||
"System": "Platform",
|
||||
"Group": "Setting Definitions",
|
||||
"Term": "Abp.Account.IsSelfRegistrationEnabled",
|
||||
"Url": "/admin/list/App.SettingDefinitions",
|
||||
"Weight": "0.8"
|
||||
},
|
||||
{
|
||||
"System": "Platform",
|
||||
"Group": "Setting Definitions",
|
||||
"Term": "Abp.Account.IsSelfRegistrationEnabled",
|
||||
"Url": "/admin/list/App.SettingDefinitions",
|
||||
"Weight": "0.7"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in a new issue