ObjectRepository - .NET qaabka kaydka xusuusta ee mashaariicda gurigaaga

Waa maxay sababta dhammaan xogta lagu kaydiyo?

Si loo kaydiyo mareegaha ama xogta dhabarka dambe, rabitaanka ugu horreeya ee dadka miyir-qabka leh ayaa noqon doona inay doortaan kaydka SQL. 

Laakiin mararka qaarkood fikradda ayaa maskaxda ku haysa in qaabka xogta uusan ku habboonayn SQL: tusaale ahaan, marka la dhisayo raadinta ama garaafka bulshada, waxaad u baahan tahay inaad raadiso xiriirro adag oo ka dhexeeya walxaha. 

Xaaladda ugu xun waa marka aad ka shaqeyso koox iyo saaxiibkiis uusan garaneynin sida loo dhiso weydiimo degdeg ah. Intee jeer ayaad ku bixisay xallinta mashaakilaadka N+1 oo aad dhistay tusmo dheeraad ah si SELECT ee bogga ugu weyn uu u dhammaystiro waqti macquul ah?

Habka kale ee caanka ah waa NoSQL. Dhawr sano ka hor waxaa jiray buun buunin badan oo mawduucan ku saabsan - munaasabad kasta oo ku habboon waxay geeyeen MongoDB waxayna ku faraxsan yihiin jawaabaha qaabka json (sida jidka ag fadhida, immisa biro ayaa qasab kugu ah in aad geliso xiriirinta wareegtada ah ee dukumeentiyada darteed?).

Waxaan soo jeedinayaa in la isku dayo mid kale, hab kale - maxaad isku dayi weyday inaad ku kaydiso dhammaan xogta xusuusta codsiga, adigoo si xilliyo ah u badbaadinaya kaydinta random (faylka, xogta fog)? 

Xusuustu waxay noqotay mid raqiis ah, iyo xog kasta oo suurtagal ah ee mashaariicda yaryar iyo kuwa dhexdhexaadka ah badankood waxay ku habboonaan doonaan 1 GB oo xusuusta ah. (Tusaale ahaan, mashruuca guriga aan jeclahay waa tracker dhaqaale, kaas oo xajiya xisaabaadka maalinlaha ah iyo taariikhda kharashyadayda, hadhaaga, iyo wax kala iibsigayga muddo sannad iyo badh ah, waxay isticmaashaa kaliya 45 MB ee xusuusta.)

Faa'iido:

  • Helitaanka xogta ayaa noqonaysa mid sahlan - uma baahnid inaad ka walwasho su'aalaha, culeyska caajiska ah, sifooyinka ORM, waxaad la shaqeysaa walxaha C # caadiga ah;
  • Ma jiraan wax dhibaato ah oo la xidhiidha helitaanka dunta kala duwan;
  • Aad u dhaqso badan - ma jiro codsiyo shabakad, ma jirto kood u turjumay luqadda weydiinta, looma baahna (de) taxane walxaha;
  • Waa la aqbali karaa in lagu kaydiyo xogta qaab kasta - ha ahaato XML ee saxanka, ama SQL Server, ama kaydinta miiska Azure.

Ogolaansho:

  • Miisaanka tooska ah waa lumay, natiijaduna, eber meel dhigista wakhtiga dhimista lama samayn karo;
  • Haddii codsigu burburo, waxaa laga yaabaa inaad qayb ahaan lumiso xogta. (Laakin codsigayagu waligiis ma burburo, sax?)

Sidee u shaqeeyaan?

Algorithm waa sida soo socota:

  • Bilawga, xidhiidh ayaa la sameeyaa kaydinta xogta, xogtana waa la shubaa;
  • Qaab shayga, tusmooyinka aasaasiga ah, iyo tusmooyinka xidhiidhka (1:1, 1: badan) ayaa la dhisay;
  • Rukunid ayaa loo sameeyay isbeddelada guryaha shayga (INotifyPropertyChanged) iyo ku darista ama ka saarida walxaha ururinta (INotifyCollectionChanged);
  • Marka isdiiwaangelinta la kiciyo, shayga la beddelay ayaa lagu daraa safka loogu talagalay in lagu qoro kaydinta xogta;
  • Isbeddellada kaydinta waxaa lagu keydiyaa xilliyo (waqti-meeraha) oo ku jira dunta gadaal;
  • Markaad ka baxdo arjiga, isbeddelada ayaa sidoo kale lagu kaydiyaa kaydinta.

Tusaalaha kood

Ku darida ku tiirsanaanta lagama maarmaanka ah

// Основная библиотека
Install-Package OutCode.EscapeTeams.ObjectRepository
    
// Хранилище данных, в котором будут сохраняться изменения
// Используйте то, которым будете пользоваться.
Install-Package OutCode.EscapeTeams.ObjectRepository.File
Install-Package OutCode.EscapeTeams.ObjectRepository.LiteDb
Install-Package OutCode.EscapeTeams.ObjectRepository.AzureTableStorage
    
// Опционально - если нужно хранить модель данных для Hangfire
// Install-Package OutCode.EscapeTeams.ObjectRepository.Hangfire

Waxaan sharaxnaa qaabka xogta ee lagu kaydin doono kaydinta

public class ParentEntity : BaseEntity
{
    public ParentEntity(Guid id) => Id = id;
}
    
public class ChildEntity : BaseEntity
{
    public ChildEntity(Guid id) => Id = id;
    public Guid ParentId { get; set; }
    public string Value { get; set; }
}

Kadib qaabka shayga:

public class ParentModel : ModelBase
{
    public ParentModel(ParentEntity entity)
    {
        Entity = entity;
    }
    
    public ParentModel()
    {
        Entity = new ParentEntity(Guid.NewGuid());
    }
    
    public Guid? NullableId => null;
    
    // Пример связи 1:Many
    public IEnumerable<ChildModel> Children => Multiple<ChildModel>(x => x.ParentId);
    
    protected override BaseEntity Entity { get; }
}
    
public class ChildModel : ModelBase
{
    private ChildEntity _childEntity;
    
    public ChildModel(ChildEntity entity)
    {
        _childEntity = entity;
    }
    
    public ChildModel() 
    {
        _childEntity = new ChildEntity(Guid.NewGuid());
    }
    
    public Guid ParentId
    {
        get => _childEntity.ParentId;
        set => UpdateProperty(() => _childEntity.ParentId, value);
    }
    
    public string Value
    {
        get => _childEntity.Value;
        set => UpdateProperty(() => _childEntity.Value, value
    }
    
    // Доступ с поиском по индексу
    public ParentModel Parent => Single<ParentModel>(ParentId);
    
    protected override BaseEntity Entity => _childEntity;
}

Ugu dambayntiina, qaybta kaydka lafteeda si loo helo xogta:

public class MyObjectRepository : ObjectRepositoryBase
{
    public MyObjectRepository(IStorage storage) : base(storage, NullLogger.Instance)
    {
        IsReadOnly = true; // Для тестов, позволяет не сохранять изменения в базу
    
        AddType((ParentEntity x) => new ParentModel(x));
        AddType((ChildEntity x) => new ChildModel(x));
    
        // Если используется Hangfire и необходимо хранить модель данных для Hangfire в ObjectRepository
        // this.RegisterHangfireScheme(); 
    
        Initialize();
    }
}

Samee tusaale ahaan kaydka Object:

var memory = new MemoryStream();
var db = new LiteDatabase(memory);
var dbStorage = new LiteDbStorage(db);
    
var repository = new MyObjectRepository(dbStorage);
await repository.WaitForInitialize();

Haddii mashruucu isticmaali doono HangFire

public void ConfigureServices(IServiceCollection services, ObjectRepository objectRepository)
{
    services.AddHangfire(s => s.UseHangfireStorage(objectRepository));
}

Gelida shay cusub:

var newParent = new ParentModel()
repository.Add(newParent);

Iyadoo wacitaankan, shayga Qaabka Waalidka waxaa lagu daraa khasnadaha maxalliga ah iyo safka wax loogu qoro kaydka. Sidaa darteed, qalliinkan wuxuu qaadanayaa O (1), shaygan waxaa lagu shaqeyn karaa isla markiiba.

Tusaale ahaan, si aad u heshid shaygan kaydka oo aad hubiso in shayga la soo celiyay uu yahay isla tusaale:

var parents = repository.Set<ParentModel>();
var myParent = parents.Find(newParent.Id);
Assert.IsTrue(ReferenceEquals(myParent, newParent));

Maxaa dhacaya? Deji () soo noqda Qaamuuska miiska, oo ka kooban Qaamuuska isku midka ah waxayna bixisaa hawlqabad dheeraad ah oo ku saabsan tusmooyinka aasaasiga ah iyo kuwa sare. Tani waxay kuu ogolaaneysaa inaad hesho habab aad ku raadiso Id (ama tusmooyinka kale ee isticmaalaha) adoon si buuxda ugu soo celcelin dhammaan walxaha.

Marka walxaha lagu daro Kaydka Object is-diiwaangelinta ayaa lagu daraa si loo beddelo hantidooda, markaa isbeddel kasta oo ku yimaadda guryaha ayaa sidoo kale keena in shaygan lagu daro safka qorista. 
Cusbooneysiinta guryaha dibadda waxay la mid tahay ku shaqeynta shay POCO:

myParent.Children.First().Property = "Updated value";

Waxaad u tirtiri kartaa shay siyaabaha soo socda:

repository.Remove(myParent);
repository.RemoveRange(otherParents);
repository.Remove<ParentModel>(x => !x.Children.Any());

Tani waxay sidoo kale ku daraysaa shayga safka tirtirka.

Sidee wax badbaadintu u shaqeysaa?

Kaydka Object marka walxaha la kormeero ay isbedelaan (ama ku darista ama tirtirida, ama beddelka guryaha), waxay kicisaa dhacdo Qaabka la beddelayku biirtay Kaydinta. Hirgelinta Kaydinta marka ay dhacdo dhacdo Qaabka la beddelay isbeddelada ayaa la geliyaa 3 saf - isku-darka, cusboonaysiinta, iyo tirtiridda.

Sidoo kale fulinta Kaydinta Marka la bilaabayo, waxay abuuraan waqti-geeye keenaya in isbeddellada la badbaadiyo 5-tii ilbiriqsi kasta. 

Intaa waxaa dheer, waxaa jira API si loogu qasbo wicitaanka badbaadinta: Kaydi () ObjectRepository..

Badbaadin kasta ka hor, hawlgallada aan macnaha lahayn ayaa marka hore laga saarayaa safka (tusaale ahaan, dhacdooyinka nuqul ka mid ah - marka shay laba jeer la beddelay ama si degdeg ah loogu daray/saaray shay), ka dibna kaliya badbaadinta lafteeda. 

Xaaladaha oo dhan, shayga hadda jira oo dhan waa la badbaadiyay, markaa waxaa suurtogal ah in walxaha loo kaydiyo si ka duwan sidii hore loo bedelay, oo ay ku jiraan noocyo cusub oo walxood oo ka duwan markii lagu daray safka.

Maxaa kale oo jira?

  • Dhammaan maktabaduhu waxay ku salaysan yihiin .NET Standard 2.0. Waxa loo isticmaali karaa mashruuc kasta oo .NET casri ah.
  • API waa dun ammaan ah. Ururinta gudaha waxaa la hirgeliyaa iyadoo lagu salaynayo Qaamuuska isku midka ah, hawlwadeenada dhacdada ama waxay leeyihiin quful ama uma baahna iyaga. 
    Waxa kaliya ee mudan in la xasuusto waa in la waco ObjectRepository.Save();
  • Tilmaamaha aan sabab lahayn (waxay u baahan yihiin gaar):

repository.Set<ChildModel>().AddIndex(x => x.Value);
repository.Set<ChildModel>().Find(x => x.Value, "myValue");

Yaa isticmaala?

Shakhsi ahaan, waxaan bilaabay isticmaalka habkan dhammaan mashaariicda hiwaayadda sababtoo ah way ku habboon tahay oo uma baahna kharashyo badan qorista lakabka helitaanka xogta ama geynta kaabayaasha culus. Shakhsi ahaan, kaydinta xogta litb ama fayl inta badan waa igu filan tahay. 

Laakiin waagii hore, marka bilawga hadda maqan ee EscapeTeams (Waxaan u maleeyay in halkan ay tahay, lacag - laakiin maya, waayo-aragnimo mar kale) - loo isticmaalo in lagu kaydiyo xogta Azure Table Storage.

Qorshayaasha mustaqbalka

Waxaan jeclaan lahaa inaan hagaajiyo mid ka mid ah faa'iido darrada ugu weyn ee habkan - miisaan toosan. Si tan loo sameeyo, waxaad u baahan tahay ama waxaad u baahan tahay ama samee go'aan xoog leh oo ah in xogta la midka ah ee xaaladaha kala duwan aysan isbeddelin, ama ha u beddelaan mabda'a "kan ugu dambeeya waa sax."

Marka laga eego dhinaca farsamada, waxaan u arkaa nidaamka soo socda sida suurtogalka ah:

  • Kaydi EventLog iyo Sawir-qaade halkii aad ka isticmaali lahayd qaabka shayga
  • Soo hel tusaalooyin kale (ku dar dhammaadka tusaalooyinka oo dhan goobaha? daahfurka udp? sayid/addoon?)
  • Ku celceli inta u dhaxaysa dhacdooyinka EventLog iyada oo la adeegsanayo algorithm kasta oo la isku raacsan yahay, sida RAFT.

Waxa kale oo jirta dhibaato kale oo aniga iga walwalsa - tirtirka cascade, ama ogaanshaha kiisaska tirtirka walxaha kuwaas oo xidhiidh ka leh shay kale. 

Lambarka isha

Haddii aad akhriday dhammaan jidka halkan, markaa waxa hadhay oo dhan waa inaad akhrido koodka; waxaa laga heli karaa GitHub:
https://github.com/DiverOfDark/ObjectRepository

Source: www.habr.com

Add a comment