Ana içeriğe atla

Arama Komut Dosyalarını İşleme

 Şimdi Film sayfasını açarsak kiracı2'nin sadece kiracısına ait filmleri görebildiğini göreceğiz . 

Ancak bir filme oyuncu eklemeye çalıştığınızda tüm kişiler gösterilir.:

Kiracı2 Tüm Ülkeler

Bu veriler dinamik bir komut dosyası aracılığıyla komut dosyası tarafına beslenir. 

Bu verileri yakın zamanda ele aldığımız Liste hizmetlerine yüklemiyor .

Bu açılır listeyi oluşturan arama komut dosyası PersonRow.cs'de tanımlanmıştır :

namespace MultiTenancy.MovieDB
{
    [ConnectionKey("Default"), Module("MovieDB"), TableName("[mov].[Person]")]
    [DisplayName("Person"), InstanceName("Person")]
    [ReadPermission("Administration:General")]
    [ModifyPermission("Administration:General")]
    [LookupScript("MovieDB.Person")] // <-- This is the definition
    public sealed class PersonRow : Row<PersonRow.RowFields>, IIdRow, INameRow, IMultiTenantRow
    {
        [DisplayName("Person Id"), Identity, IdProperty]
        public int? PersonId
        {
            get => fields.PersonId[this];
            set => fields.PersonId[this] = value;
        }

Bazen verileri özelleştirmek için özel arama komut dosyaları kullanmamız gerekir. 

 

Örneğin kuzey rüzgarı örneği TedarikçiCountryLookup . 

 

Bu arama sınıfı RowLookupScript temel sınıfından türetilir Bu durumda bu tür aramaları da halletmemiz gerekir.

Arama sorgusunu mevcut kiracıya göre filtrelememiz gerekir. 

Daha sonra ele almamız gereken diğer arama komut dosyalarına hazırlanmak için yeni bir temel sınıf oluşturalım.

using Serenity;
using Serenity.Abstractions;
using Serenity.Data;
using Serenity.Web;
using System;

namespace MultiTenancy
{
    public class MultiTenantRowLookupScript<TRow> :
            RowLookupScript<TRow>
            where TRow : class, IRow, IMultiTenantRow, new()
    {
        public ITwoLevelCache TwoLevelCache { get; }
        public IUserAccessor UserAccessor { get; }

        public MultiTenantRowLookupScript(ISqlConnections sqlConnections, ITwoLevelCache twoLevelCache, IUserAccessor userAccessor) : base(sqlConnections)
        {
            Expiration = TimeSpan.FromDays(-1);
            TwoLevelCache = twoLevelCache ?? throw new ArgumentNullException(nameof(twoLevelCache));
            UserAccessor = userAccessor ?? throw new ArgumentNullException(nameof(userAccessor));
        }

        protected override void PrepareQuery(SqlQuery query)
        {
            base.PrepareQuery(query);
            AddTenantFilter(query);
        }

        protected void AddTenantFilter(SqlQuery query)
        {
            var r = new TRow();
            query.Where(r.TenantIdField == UserAccessor.User.GetTenantId());
        }

        public override string GetScript()
        {
            return TwoLevelCache.GetLocalStoreOnly("MultiTenantLookup:" +
                    this.ScriptName + ":" +
                    UserAccessor.User.GetTenantId(),
                    TimeSpan.FromHours(1),
                new TRow().GetFields().GenerationKey, () =>
                {
                    return base.GetScript();
                });
        }
    }
}

Bu, çok kiracılı arama komut dosyaları için temel sınıfımız olacaktır.

Önbelleğe almayı devre dışı bırakmak için ilk önce sona erme tarihini negatif bir zaman aralığına ayarladık. Bunu neden yapmak zorundayız? Çünkü dinamik komut dosyası yöneticisi, arama komut dosyalarını anahtarlarıyla önbelleğe alır. Ancak TenantId değerlerine dayalı bir arama komut dosyasının birden çok sürümüne sahip olacağız.

Önbelleğe almayı dinamik komut dosyası yöneticisi düzeyinde kapatacağız ve önbelleğe almayı GetScript yönteminde kendimiz halledeceğiz. GetScript yönteminde , arama betiğimizi oluşturan temel yöntemi çağırmak ve sonucunu TenantId içeren bir önbellek anahtarıyla önbelleğe almak için TwoLevelCache.GetLocalStoreOnly kullanıyoruz .

TwoLevelCache sınıfı hakkında daha fazla bilgi için ilgili bölüme bakın.

Hazırlık Sorgu yöntemini geçersiz kılarak , tıpkı liste hizmet işleyicilerinde yaptığımız gibi geçerli TenantId'ye göre bir filtre ekliyoruz .

Şimdi bu yeni temel sınıfı kullanarak TedarikçiCountryLookup adlı kuzey rüzgarı örnek aramasını nasıl uygulayacağımızı görelim :

namespace MultiTenancy.Northwind.Scripts
{
    using Serenity.ComponentModel;
    using Serenity.Data;
    using Serenity.Web;

    [LookupScript("Northwind.SupplierCountry")]
    public class SupplierCountryLookup :
        MultiTenantRowLookupScript<SupplierRow>
    {
        public SupplierCountryLookup(ISqlConnections sqlConnections, ITwoLevelCache twoLevelCache, IUserAccessor userAccessor) : base(sqlConnections)
        {
            IdField = TextField = "Country";
        }

        protected override void PrepareQuery(SqlQuery query)
        {
            var fld = SupplierRow.Fields;
            query.Distinct(true)
                .Select(fld.Country)
                .Where(
                    new Criteria(fld.Country) != "" &
                    new Criteria(fld.Country).IsNotNull());

            AddTenantFilter(query);
        }

        protected override void ApplyOrder(SqlQuery query)
        {
        }
    }
}

AddTenantFilter yöntemini manuel olarak çağırdık , çünkü burada temel HazırlıkQuery yöntemini çağırmıyorduk (bu nedenle temel sınıf tarafından çağrılmayacak).

Satırlardaki Komut Dosyası Bildirimlerini Arama

Artık çözmemiz gereken bir sorunumuz daha var. Satırlardaki [LookupScript] özelliği.

Varsayılan olarak LookupScript, türe dayalı bir arama örneği oluşturur RowLookupScript<>MultiTenantRowLookupScript<>Bu çok kiracılı satırlar için bunu olarak değiştirmemiz gerekiyor .

Kişi aramayı düzeltelim. PersonRow'da [LookupScript] niteliğini aşağıdaki gibi değiştirin .

[ConnectionKey("Default"), Module("MovieDB"), TableName("[mov].[Person]")]
[DisplayName("Person"), InstanceName("Person")]
[ReadPermission("Administration:General")]
[ModifyPermission("Administration:General")]
[LookupScript("MovieDB.Person", LookupType = typeof(MultiTenantRowLookupScript<>))]
public sealed class PersonRow : Row<PersonRow.RowFields>, IIdRow, INameRow, IMultiTenantRow
{
    //...

Bunun Serenity 2.9.22+ gerektirdiğini unutmayın.

GenreRow satırı için de benzerini yapın (LookupType ekleyin) .

Artık MovieDB çoklu kiracılığı destekliyor.

Gözden kaçırdığım bazı aksaklıklar olabilir, varsa Serenity Github deposunda bildirin.

Bu blogdaki popüler yayınlar

Code generetor ile oluşturulan dosyaların açıklamaları

  1. Sunum (Presentation/UI) Katmanı (Kullanıcı arayüzü - HTML, TypeScript, Dialog, Grid) 🔹 XYZPage.ts 📌 Ne İşe Yarar? Kullanıcı arayüzünün TypeScript tarafındaki tanımıdır. Serenity'nin Dialog ve Grid bileşenlerini içeren bir TypeScript sınıfıdır. 📌 Çok Katmanlı Mimarideki Yeri: Sunum Katmanı (Presentation Layer) Kullanıcıdan veri almak ve göstermek için kullanılır. 🔹 XYZGrid.ts 📌 Ne İşe Yarar? Tablo (Grid) yapısını oluşturur ve verileri listeler. Filtreleme, sıralama ve sayfalama işlemleri için kullanılır. columnsKey ile hangi kolonların gösterileceğini belirler. 📌 Çok Katmanlı Mimarideki Yeri: Sunum Katmanı (Presentation Layer) Kullanıcının verileri listelediği ve etkileşimde bulunduğu yerdir. 🔹 XYZDialog.ts 📌 Ne İşe Yarar? CRUD (Create, Read, Update, Delete) işlemlerini yöneten pencere (modal) bileşeni Kullanıcı form aracılığıyla veri ekler, günceller veya siler. XYZForm.cs ile birlikte çalışır. 📌 Çok Katmanlı Mimarideki Yeri: Sunum Katmanı (Presentation Layer) Kull...

Serenity Web Nedir?

   Serenity  , açık kaynak teknolojileri üzerine kurulu bir ASP.NET Core/TypeScript uygulama platformudur. Standart kodlardan kaçınarak, tekrarlanan görevlere harcanan zamanı azaltarak ve en iyi yazılım tasarımı uygulamalarını uygulayarak bakım maliyetlerini düşürürken geliştirmeyi kolaylaştırmayı amaçlamaktadır. Serene  , Serenity platformunu temel alan ücretsiz, açık kaynaklı başlangıç ​​uygulama şablonumuzdur.  Bu dokümantasyon aracılığıyla eğitimimiz ve diğer örnekler için esas olarak Serene'yi kullanacağız. StartSharp  , ücretli müşterilerimize sunduğumuz premium uygulama şablonudur.  Daha gösterişli bir temaya ve bazı ekstra özelliklere  ek olarak Serene'deki her şeyi içerir  .  İkisi de Serenity platformunu temel alıyor. Adında Ne Var Serenity'nin sözlük anlamları  barış  ,  rahatlık  ve  sakinliktir  . Serenity ile bunu başarmaya çalışıyoruz.  Umarız yükledikten ve kullandıktan sonra siz de bu ş...