public virtual IDtoMetadataBuilder <TDto> AddLookup <TLookupDto>(string memberName, string dataValueField, string?dataTextField, Expression <Func <TLookupDto, bool> >?baseFilter = null, string?lookupName = null)
            where TLookupDto : class
        {
            if (memberName == null)
            {
                throw new ArgumentNullException(nameof(memberName));
            }

            if (dataValueField == null)
            {
                throw new ArgumentNullException(nameof(dataValueField));
            }

            if (_dtoMetadata == null)
            {
                throw new InvalidOperationException($"{nameof(AddDtoMetadata)} must be called first");
            }

            DtoMemberLookup lookup = new DtoMemberLookup
            {
                DtoMemberName  = memberName,
                DataTextField  = dataTextField,
                DataValueField = dataValueField,
                LookupDtoType  = typeof(TLookupDto).GetTypeInfo().FullName
            };

            if (baseFilter != null)
            {
                lookup.BaseFilter_JS = BuildLookupJsFilterFromLambdaExpression(baseFilter, lookup);
            }

            _dtoMetadata.MembersLookups.Add(lookup);

            return(this);
        }
        protected virtual string BuildLookupJsFilterFromLambdaExpression <TLookupDto>(Expression <Func <TLookupDto, bool> > baseFilter, DtoMemberLookup lookup)
            where TLookupDto : class
        {
            if (baseFilter == null)
            {
                throw new ArgumentNullException(nameof(baseFilter));
            }

            if (baseFilter.Parameters.ExtendedSingle("Finding base filter parameters").Name != "it")
            {
                throw new Exception("base filter's parameter name must be 'it'. For example it => it.Id == 1");
            }

            return(baseFilter.CompileToJavascript(JavascriptCompilationOptions));
        }