seed/data Seeder GlobalSearch

This commit is contained in:
Sedat ÖZTÜRK 2026-09-04 14:25:35 +03:00
parent 3db82df964
commit a1a76b1a95
6 changed files with 74 additions and 64 deletions

View file

@ -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.

View file

@ -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(),

View file

@ -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>

View file

@ -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",

View file

@ -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);

View 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"
}
]
}