ObjectRepository - .NET tsarin ma'ajiya na ƙwaƙwalwar ajiya don ayyukan gidan ku

Me yasa ake adana duk bayanan a ƙwaƙwalwar ajiya?

Don adana gidan yanar gizo ko bayanan baya, burin farko na mafi yawan mutane masu hankali shine zabar bayanan SQL. 

Amma wani lokacin tunanin yakan zo a hankali cewa samfurin bayanan bai dace da SQL ba: alal misali, lokacin gina bincike ko jadawali na zamantakewa, kuna buƙatar bincika alaƙa mai rikitarwa tsakanin abubuwa. 

Mafi munin yanayi shine lokacin da kuke aiki a cikin ƙungiya kuma abokin aiki bai san yadda ake gina tambayoyin gaggawa ba. Yaya tsawon lokaci kuka ɓata don magance matsalolin N+1 da gina ƙarin fihirisa ta yadda SELECT a babban shafi zai cika cikin lokaci mai ma'ana?

Wata sanannen hanyar ita ce NoSQL. Shekaru da yawa da suka gabata an yi ta yayatawa game da wannan batu - ga kowane lokaci mai dacewa sun tura MongoDB kuma sun yi farin ciki da amsoshin ta hanyar takaddun json (Af, sanduna nawa ne kuka saka saboda madauwari da ke cikin takaddun?).

Ina ba da shawarar gwada wani, madadin hanyar - me zai hana a gwada adana duk bayanan a cikin ƙwaƙwalwar aikace-aikacen, adana lokaci-lokaci zuwa ma'ajin bazuwar (fayil, bayanan nesa)? 

Ƙwaƙwalwar ajiya ta zama mai arha, kuma duk wani bayanan da za a iya yi don yawancin ƙananan ayyuka da matsakaita za su dace da 1 GB na ƙwaƙwalwar ajiya. (Misali, aikin gida da na fi so shine kudi tracker, wanda ke adana ƙididdiga na yau da kullun da tarihin kashe kuɗi na, ma'auni, da ma'amaloli na tsawon shekara ɗaya da rabi, yana cinye 45 MB na ƙwaƙwalwar ajiya kawai.)

Sakamakon:

  • Samun damar yin amfani da bayanai ya zama mafi sauƙi - ba kwa buƙatar damuwa game da tambayoyi, ɗora nauyi, fasalulluka na ORM, kuna aiki tare da abubuwan C # na yau da kullun;
  • Babu matsaloli masu alaƙa da samun dama daga zaren daban-daban;
  • Da sauri sosai - babu buƙatun hanyar sadarwa, babu fassarar lamba cikin harshen tambaya, babu buƙatar (de) serialization na abubuwa;
  • An yarda da adana bayanai ta kowace hanya - ya kasance a cikin XML akan faifai, ko a cikin SQL Server, ko a cikin Azure Table Storage.

Fursunoni:

  • An yi hasarar ma'auni na tsaye, kuma a sakamakon haka, ba za a iya yin aiki ba;
  • Idan aikace-aikacen ya yi karo, za ku iya rasa wani ɓangare na bayanai. (Amma aikace-aikacen mu baya yin faɗuwa, daidai?)

Yaya ta yi aiki?

Algorithm shine kamar haka:

  • A farkon, an kafa haɗin kai tare da ajiyar bayanai, kuma ana loda bayanai;
  • Samfurin abu, fihirisa na farko, da alamomin alaƙa (1:1, 1: da yawa) an gina su;
  • An ƙirƙiri biyan kuɗi don canje-canje a cikin abubuwan abubuwan (INotifyPropertyChanged) da don ƙara ko cire abubuwa a cikin tarin (INotifyCollectionChanged);
  • Lokacin da aka kunna biyan kuɗi, ana ƙara abin da aka canza zuwa jerin gwano don rubutawa zuwa ajiyar bayanai;
  • Ana adana canje-canje ga ma'ajiyar lokaci-lokaci (a kan mai ƙidayar lokaci) a cikin zaren bango;
  • Lokacin da kuka fita aikace-aikacen, ana kuma adana canje-canje zuwa ma'ajiyar.

Misali Code

Ƙara abubuwan da suka dace

// Основная библиотека
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

Mun bayyana samfurin bayanan da za a adana a cikin ma'ajiyar

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; }
}

Sai samfurin abu:

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;
}

Kuma a ƙarshe, ajin ajiyar kanta don samun damar bayanai:

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();
    }
}

Ƙirƙiri Misalin Ma'ajiyar Abu:

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

Idan aikin zai yi amfani da HangFire

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

Saka sabon abu:

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

Tare da wannan kira, abu ParentModel Ana ƙara zuwa duka ma'ajiyar gida da jerin gwano don rubutawa zuwa bayanan bayanai. Don haka, wannan aikin yana ɗaukar O (1), kuma ana iya aiki da wannan abu nan da nan.

Misali, don nemo wannan abu a cikin ma'ajiya kuma a tabbatar da cewa abin da aka dawo daidai ne:

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

Me ZE faru? Saita () ya dawo Littafin ƙamus, wanda ya ƙunshi Ƙamus na Daidaitawa kuma yana ba da ƙarin ayyuka na firamare da sakandare. Wannan yana ba ku damar samun hanyoyin bincike ta Id (ko wasu firikwensin mai amfani na sabani) ba tare da gabaɗaya akan duk abubuwa ba.

Lokacin ƙara abubuwa zuwa Takardun Abubuwan ana ƙara biyan kuɗi don canza kaddarorin su, don haka duk wani canjin kaddarorin kuma yana haifar da ƙara wannan abu zuwa layin rubutu. 
Ana ɗaukaka kaddarorin daga waje yayi kama da aiki tare da abun POCO:

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

Kuna iya share abu ta hanyoyi masu zuwa:

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

Wannan kuma yana ƙara abu zuwa layin gogewa.

Ta yaya tanadi yake aiki?

Takardun Abubuwan lokacin da abubuwan da aka sa ido suka canza (ko dai ƙara ko sharewa, ko canza kaddarorin), suna ɗaga wani taron Model Canjabiyan kuɗi zuwa Adana. Ayyuka Adana lokacin da wani lamari ya faru Model Canja Ana sanya canje-canje a cikin layukan 3 - don ƙarawa, don sabuntawa, da sharewa.

Hakanan aiwatarwa Adana da farawa, suna ƙirƙiri mai ƙidayar lokaci wanda ke haifar da adana canje-canje kowane sakan 5. 

Bugu da kari, akwai API don tilasta kiran ajiyewa: Abubuwan Taɗi.Ajiye().

Kafin kowane ajiyewa, ana fara cire ayyuka marasa ma'ana daga jerin gwano (misali, abubuwan da suka faru na kwafi - lokacin da aka canza abu sau biyu ko da sauri ƙarawa / cire abubuwa), sannan sai kawai ajiyar kanta. 

A kowane hali, ana adana duk abin da ke yanzu, don haka yana yiwuwa an adana abubuwa a cikin wani tsari na daban fiye da yadda aka canza su, gami da sabbin nau'ikan abubuwa fiye da lokacin da aka ƙara su cikin jerin gwano.

Menene kuma?

  • Duk ɗakunan karatu suna dogara ne akan NET Standard 2.0. Ana iya amfani da shi a kowane aikin .NET na zamani.
  • API ɗin zaren lafiyayye ne. Ana aiwatar da tarin ciki bisa ga Ƙamus na Daidaitawa, Masu gudanar da taron ko dai suna da makullai ko kuma ba sa buƙatar su. 
    Abinda yakamata a tuna shine a kira ObjectRepository.Ajiye();
  • Fihirisar sabani (yana buƙatar keɓancewa):

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

Wanene yake amfani da shi?

Da kaina, na fara amfani da wannan hanyar a cikin duk ayyukan sha'awa saboda ya dace kuma baya buƙatar manyan kuɗaɗe don rubuta layin samun damar bayanai ko tura manyan abubuwan more rayuwa. Da kaina, adana bayanai a cikin litb ko fayil yawanci ya ishe ni. 

Amma a baya, lokacin da bacewar farawa EscapeTeams (Na yi tunani a nan shi ne, kudi - amma a'a, kwarewa sake) - ana amfani dashi don adana bayanai a cikin Azure Table Storage.

Shirye-shirye na nan gaba

Ina so in gyara ɗaya daga cikin manyan rashin lahani na wannan hanya - sikelin kwance. Don yin wannan, kuna buƙatar ko dai rarraba ma'amaloli (sic!), Ko yanke shawara mai ƙarfi cewa bayanai iri ɗaya daga lokuta daban-daban bai kamata su canza ba, ko ku bar su su canza bisa ga ka'idar "wanda shine na ƙarshe shine daidai."

Daga mahangar fasaha, ina ganin makirci mai zuwa kamar yadda zai yiwu:

  • Ajiye EventLog da Snapshot maimakon samfurin abu
  • Nemo wasu misalan (ƙara ƙarshen kowane misali zuwa saitunan? gano udp? master/bawa?)
  • Maimaita tsakanin abubuwan EventLog ta kowane algorithm yarjejeniya, kamar RAFT.

Akwai kuma wata matsala da ke damuna - gogewar cascade, ko gano lokuta na goge abubuwan da ke da alaƙa daga wasu abubuwa. 

Source

Idan kun karanta har zuwa nan, to abin da ya rage shine karanta lambar; ana iya samun ta akan GitHub:
https://github.com/DiverOfDark/ObjectRepository

source: www.habr.com

Add a comment