Как стать автором
Обновить
33
0
Dmitry Tikhonov @0x1000000

Software Developer

Отправить сообщение

Победить эффект "зловещий долины" у нейронок пока не выходит. Чувствуется, что что-то с этими картинками не так.

Есть ещё один очень популярный язык программирование в котором всё время приходится учитывать троичную логику (и даже в каком-то смысле четверичную) — это JavaScript со своими undefined и null
Скрытый текст
var a = {};

console.log(a.b); // undefined
console.log(Object.keys(a)); // []

a.b = undefined;
console.log(a.b); // undefined
console.log(Object.keys(a)); // ["b"]


Забавно, в свое время самостоятельно дошел до идеи «Closure Table», а это оказывается уже известный паттерн )

Могу лишь добавить, что если данных в основной таблице с деревом не очень много, а возиться с обновлением «Closure Table» не охота, то в принципе, можно обойтись и «view» c рекурсивной CTE, позже заменив её на реальную таблицу (в случае проблем с производительностью).
Пример CTE
;WITH CTE_Recursive AS (
       SELECT 
              Id,
              ParentId
       FROM dbo.TreeData
UNION ALL
       SELECT 
              [PREVIOUS].Id,
              [CURRENT].ParentId
       FROM dbo.TreeData
              [CURRENT]
       INNER JOIN CTE_Recursive
              [PREVIOUS] ON
              [PREVIOUS].ParentId = [CURRENT].Id
)
,CTE_TreeRelation AS
(
        SELECT 
                     Id, 
                     ParentId
              FROM CTE_Recursive
    UNION ALL
        SELECT 
                     Id, Id as ParentId
              FROM dbo.TreeData
) 
SELECT * FROM CTE_TreeRelation


Хм... а сталкивался на практике с прямо противоположной ситуацией, когда JSON выпиливался и внедрялся EAV как раз из-за проблем с производительностью - с EAV всё стало в тысячи раз быстрее (в буквальном смысле).

Мне кажется, что данные, в предложенной вами структуре таблиц, будет сложнее обновлять т.к. всегда придется работать с двумя таблицами.

filter без вложенных селектов

Идея в том, что фильтр приходит "извне", где не знают о структуре хранения данных, и предикат по полю "списку" (например [Protocol] IN ('4G', '5G')) может быть вложен внутрь сложного булевского выражения. Замена такого предиката на EXISTS(SELECT ...) позволит сохранить логику исходного фильтра.

Как при этом сделать сквозную сортировку и пагинацию, если фильтрация идет одновременно по нескольким полям и фильтр может включать любые логические операции (как в примере из статьи)?

Нормально с JSON могут работать далеко не все SQL базы данных, и не понятно, что с производительностью (если делать индексы на JSON, то теряется динамичность).

Можно просто привязать атрибуты к категории товара. Это, собственно, и сделано в демонстрационном приложении SqGoods:

Спасибо! Поправил. Это сработала авто-замена. Должно быть " 05/29/2022, 2022–05–22, 29.05.2022 " (MM/dd/yyyy, yyyy-MM-dd, dd.MM.yyyy)

Для .Net в свое время создал SqExpress. Работает с MS SQL, Postgresql и MySql. Заточен в первую очередь на T-SQL, но для остальных диалектов создает полифилы некоторых возможностей (например MERGE).

Ещё блок finally в C# можно пропустить вообще без каких-либо исключений, достаточно намудрить с асинхронной стейт машиной. Когда-то приводил пример того, как это можно сделать.

В Option/Maybe работа цепочки вызовов (при обнаружении ошибки) как раз прерывается и происходит ранний выход.

В основном для удобства. Не надо прокидывать порты (8 для Moonlight и 1 для Wake Up On LAN) и есть доступ к настройкам роутера. Кроме того, тамошний провайдер не блокирует официально заблокированные в РФ сайты, что весьма удобно, поскольку подключившись к домашнему роутеру через VPN, можно из любой точки легко попасть на заблокированные сайты.

Спасибо за статьи!
Поделюсь своим конфигом стриминга:
1) На одной квартире стоит игровой ноутбук с карточкой NVIDIA.
2) Ноутбук подключен к роутеру, который может поднимать OPEN VPN (есть белый IP)
3) На смартфоне стоит Moonlight и Open VPN клиент.
4) Когда я хочу поиграть, НЕ находясь в квартире с ноутбуком, я подключаю VPN, бужу компьютер через “Wake up on LAN” и запускаю стриминг через Moonlight.
5) На телефоне играть не всегда удобно. т. к. меленький экран, но на другой квартире стоит большой телевизор, к которому я и подключил свой смартфон (Samsung Note 10+) используя USB Hub


Как всё это выглядит можно посмотреть на картинке:

К плюсам C# я бы отнес тот факт, что и язык, и платформу развивает одна компания, и как следствие у C# гораздо больше возможностей для развития, поскольку в случае необходимости можно и стандартную библиотеку расширить (например, Task, ValueTuple и т.д.) и рантайм поправить (Generics, dynamic)

“Вырождающееся человечество” (которого сейчас 7миллиардов) стало зависеть от технологий с того момента, как стало осколками камней стало разделывать туши животных, а после начала приготовления пищи на огне, изменения в нашем строении закрепили эту зависимость навсегда.


Это я к тому, что при наличии советующих технологий, ранее негативные признаки переходят в статус нейтральных.

Я обычно "скриптингом" на C# занимаюсь через Powershell. Очень удобно, когда нужен простенький GUI, например:


helloworldGui.ps1
$Assem = (
    “System.Windows.Forms”,
    "System.Drawing",
    "System.Core",
    "System.Data",
    "System.Xml"
    )
$Source = @”
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Infor.LMS.Utils.TranslationSearch
{

    public class Form1: Form
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(10, 10);
            this.label1.Name = "label1";
            this.label1.Font = new System.Drawing.Font("Segoe UI", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);           
            this.label1.Size = new System.Drawing.Size(148, 13);
            this.label1.Text = "Hello world!";

            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(300, 200);
            this.Controls.Add(this.label1);
            this.Margin = new System.Windows.Forms.Padding(2);
            this.Name = "Form1";
            this.Text = "Hello World!";

            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label1;

        //End of codegen

        public Form1()
        {
            InitializeComponent();
        }
    }

    public static class Program 
    {
        public static void Start()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        } 
    }
}
“@

Add-Type -ReferencedAssemblies $Assem -TypeDefinition $Source -Language CSharp 

iex "[Infor.LMS.Utils.TranslationSearch.Program]::Start()"

Преимущество перед RxJ здесь в том, что тут гораздо меньше сущностей и как результат — это проще освоить, и по опыту – проще использовать в каких-то базовых сценариях, которые и составляют 90% всех случаев. Хотя может это именно у меня не заладилось с rxJs и всё время какой-то "write only" код выходит.


На самом деле создавать, альтернативу rxJs планов не было, а основным мотивом к созданию этой библиотеки был поиск простого способа реакции на изменения входных параметров компонента так, чтобы поведение компонента всегда им соответствовало например:


<greeter [userName]=”userName” [template]=”template”> </greeter>

Здесь greeting=f(userName, template), и приветствие надо переделывать каждый раз, когда меняется один или несколько входных параметров.
Когда количество параметров растет, то такие зависимости ускользают из вида и получаются баги.


Конечно, можно было бы и rxJs здесь использовать, но это бы неоправданно усложнило код.


По поводу OnPush, явный changeDetection, нужен только если в компоненте есть асинхронное поведение, в синхронных компонентах все будет работать и с OnPush без явного detectChanges если включить immediateEvaluation.


Я так и не придумал способа того, как можно было бы получить доступ к changeDetector из библиотеки, что конечно бы упростило ситуацию.


Зато change detection вообще можно теперь отключить (.detach()) и всегда явно детектить изменения.

Значок "Тролль" — это тоже, своего рода, достижение, требующие не самых малых усилий.

1
23 ...

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность