基於SqlSugar的開發框架循序漸進介紹(31)-- 在查詢介面中實現多表聯合和單表對象的統一處理

来源:https://www.cnblogs.com/wuhuacong/archive/2023/06/03/17452609.html
-Advertisement-
Play Games

在一些複雜的業務表中間查詢數據,有時候操作會比較複雜一些,不過基於SqlSugar的相關操作,處理的代碼會比較簡單一些,以前我在隨筆《基於SqlSugar的開發框架循序漸進介紹(2)-- 基於中間表的查詢處理》介紹過基於主表和中間表的聯合查詢,而往往實際會比這個會複雜一些。本篇隨筆介紹聯合多個表進行... ...


在一些複雜的業務表中間查詢數據,有時候操作會比較複雜一些,不過基於SqlSugar的相關操作,處理的代碼會比較簡單一些,以前我在隨筆《基於SqlSugar的開發框架循序漸進介紹(2)-- 基於中間表的查詢處理》介紹過基於主表和中間表的聯合查詢,而往往實際會比這個會複雜一些。本篇隨筆介紹聯合多個表進行查詢以及樹形列表的條件展示的處理實現,系統能夠給大家一些參考思路。

1、SqlSugar的開發框架的數據查詢處理

在隨筆《基於SqlSugar的開發框架循序漸進介紹(2)-- 基於中間表的查詢處理》中,介紹過兩個表的聯合查詢,如下所示代碼所示。

/// <summary>
/// 根據用戶ID獲取對應的角色列表
/// </summary>
/// <param name="userID">用戶ID</param>
/// <returns></returns>
private async Task<List<RoleInfo>> GetByUser(int userID)
{
    var query = this.Client.Queryable<RoleInfo, User_RoleInfo>(
    (t, m) => t.Id == m.Role_ID && m.User_ID == userID)
    .Select(t => t); //聯合條件獲取對象

    query = query.OrderBy(t => t.CreateTime);//排序
    var list = await query.ToListAsync();//獲取列表
    return list;
}

/// <summary>
/// 根據機構獲取對應的角色列表(判斷機構角色中間表)
/// </summary>
/// <param name="ouID">機構的ID</param>
/// <returns></returns>
public async Task<List<RoleInfo>> GetRolesByOu(int ouID)
{
    var query = this.Client.Queryable<RoleInfo, OU_RoleInfo>(
    (t, m) => t.Id == m.Role_ID && m.Ou_ID == ouID)
    .Select(t => t); //聯合條件獲取對象

    query = query.OrderBy(t => t.CreateTime);//排序
    var list = await query.ToListAsync();//獲取列表
    return list;
}

我們對於後端的數據查詢,一般都是傳入一個條件對象,通過條件類的屬性進行構建查詢信息,如下簡單的處理操作。

/// <summary>
/// 應用層服務介面實現
/// </summary>
public class CustomerService : MyCrudService<CustomerInfo, string, CustomerPagedDto>, ICustomerService
{
    /// <summary>
    /// 自定義條件處理
    /// </summary>
    /// <param name="input">查詢條件Dto</param>
    /// <returns></returns>
    protected override ISugarQueryable<CustomerInfo> CreateFilteredQueryAsync(CustomerPagedDto input)
    {
        var query = base.CreateFilteredQueryAsync(input);

        query = query
            .WhereIF(!input.ExcludeId.IsNullOrWhiteSpace(), t => t.Id != input.ExcludeId) //不包含排除ID
            .WhereIF(!input.Name.IsNullOrWhiteSpace(), t => t.Name.Contains(input.Name)) //如需要精確匹配則用Equals
                                                                                         //年齡區間查詢
            .WhereIF(input.AgeStart.HasValue, s => s.Age >= input.AgeStart.Value)
            .WhereIF(input.AgeEnd.HasValue, s => s.Age <= input.AgeEnd.Value)

            //創建日期區間查詢
            .WhereIF(input.CreateTimeStart.HasValue, s => s.CreateTime >= input.CreateTimeStart.Value)
            .WhereIF(input.CreateTimeEnd.HasValue, s => s.CreateTime <= input.CreateTimeEnd.Value)
            ;

        return query;
    }

上面的 CreateFilteredQueryAsync 方法是一個基類函數,主要是構建該業務表的一些數據查詢的匹配處理,如對於複雜一些的查詢條件,這個內容會增加很多,不過都是可以通過代碼生成工具基於資料庫表欄位來進行一一對應的生成,從而避免人工繁瑣的敲擊代碼。

如下麵是基類函數的常規條件查詢和計數的函數處理。

/// <summary>
/// 根據條件獲取列表
/// </summary>
/// <param name="input">分頁查詢條件</param>
/// <returns></returns>
public virtual async Task<PagedResultDto<TEntity>> GetListAsync(TGetListInput input)
{
    var query = CreateFilteredQueryAsync(input);
    var totalCount = await query.CountAsync();

    query = ApplySorting(query, input);
    query = ApplyPaging(query, input);

    var list = await query.ToListAsync();

    return new PagedResultDto<TEntity>(
       totalCount,
       list
   );
}

/// <summary>
/// 根據條件計算記錄數量
/// </summary>
/// <param name="input">查詢條件,忽略分頁信息</param>
/// <returns></returns>
public virtual async Task<long> CountAsync(TGetListInput input)
{
    var query = CreateFilteredQueryAsync(input);

    var totalCount = await query.CountAsync();
    return totalCount; //返回符合條件的所有數量
}

上面的 CreateFilteredQueryAsync 方法一般會在具體的業務類中進行重寫,從而實現具體條件的查詢過濾。

 

2、對於多表的聯合處理操作

而對於複雜的多表之間的聯合查詢處理,如果分開多個函數來實現,可能會比較麻煩,而且也不夠統一,因此我們可以統一整合在CreateFilteredQueryAsync 實現。

而一些特殊的條件,我們可以在原有生成的條件分頁類裡面,增加更多的屬性,用來在聯合查詢中賦值、或者獲取值。如下圖是我們額外增加的幾個特殊的屬性,用來在其他業務表中進行關聯查詢的欄位。

由於客戶分組是在另外一張表裡面記錄的,客戶和分組之間的關聯,是通過中間表的聯合查詢獲得的。

 客戶和供應商也有一個中間表的關聯關係,因此我們如何聯合查詢,根據條件,可以通過下麵的代碼進行聯合查詢獲得。

            if (!input.GroupId.IsNullOrWhiteSpace())
            {
                // 聯合 CustomerGroup_CustomerInfo 表進行查詢
                query = this.Client.Queryable<CustomerInfo, CustomerGroup_CustomerInfo>(
                       (t, m) => t.Id == m.Customer_ID && m.CustomerGroup_ID == input.GroupId)
                       .Select(t => t).MergeTable(); //聯合條件獲取對象
            }       
            if(!input.SupplierId.IsNullOrEmpty())
            {
                query = this.Client.Queryable<CustomerInfo, Customer_SupplierInfo>(
                        (t, m) => t.Id == m.Customer_ID && m.Supplier_ID == input.SupplierId)
                        .Select(t => t).MergeTable(); //聯合條件獲取對象
            }

上面的代碼,需要註意的是,不同表之間聯合獲得的結果,如果需要整合到主表進行的查詢中,則需要使用 .MergeTable() 操作進行合併處理。

這種最終我們可以得到比較複雜一些的查詢處理了。

        /// <summary>
        /// 自定義條件處理
        /// </summary>
        /// <param name="input">查詢條件Dto</param>
        /// <returns></returns>
        protected override ISugarQueryable<CustomerInfo> CreateFilteredQueryAsync(CustomerPagedDto input)
        {
            var query = base.CreateFilteredQueryAsync(input);
            if (!input.GroupId.IsNullOrWhiteSpace())
            {
                // 聯合 CustomerGroup_CustomerInfo 表進行查詢
                query = this.Client.Queryable<CustomerInfo, CustomerGroup_CustomerInfo>(
                       (t, m) => t.Id == m.Customer_ID && m.CustomerGroup_ID == input.GroupId)
                       .Select(t => t).MergeTable(); //聯合條件獲取對象
            }       
            if(!input.SupplierId.IsNullOrEmpty())
            {
                query = this.Client.Queryable<CustomerInfo, Customer_SupplierInfo>(
                        (t, m) => t.Id == m.Customer_ID && m.Supplier_ID == input.SupplierId)
                        .Select(t => t).MergeTable(); //聯合條件獲取對象
            }

            //通過名稱或代碼查詢,任一符合即可
            query = query.WhereIF(!input.NameOrCode.IsNullOrWhiteSpace(), t => t.Name.Contains(input.NameOrCode) || t.SimpleName.Contains(input.NameOrCode) || t.HandNo.Contains(input.NameOrCode));

            query = query
               .WhereIF(!input.ExcludeId.IsNullOrWhiteSpace(), t => t.Id != input.ExcludeId) //不包含排除ID
               .WhereIF(!input.HandNo.IsNullOrWhiteSpace(), t => t.HandNo.Contains(input.HandNo)) //如需要精確匹配則用Equals
                .WhereIF(!input.Name.IsNullOrWhiteSpace(), t => t.Name.Contains(input.Name)) //如需要精確匹配則用Equals
                .WhereIF(!input.SimpleName.IsNullOrWhiteSpace(), t => t.SimpleName.Contains(input.SimpleName)) //如需要精確匹配則用Equals
                .WhereIF(!input.Province.IsNullOrWhiteSpace(), t => t.Province.Contains(input.Province)) //如需要精確匹配則用Equals
                .WhereIF(!input.City.IsNullOrWhiteSpace(), t => t.City.Contains(input.City)) //如需要精確匹配則用Equals
                .WhereIF(!input.District.IsNullOrWhiteSpace(), t => t.District.Contains(input.District)) //如需要精確匹配則用Equals
                .WhereIF(!input.Area.IsNullOrWhiteSpace(), t => t.Area.Contains(input.Area)) //如需要精確匹配則用Equals
                .WhereIF(!input.Address.IsNullOrWhiteSpace(), t => t.Address.Contains(input.Address)) //如需要精確匹配則用Equals
                .WhereIF(!input.ZipCode.IsNullOrWhiteSpace(), t => t.ZipCode.Contains(input.ZipCode)) //如需要精確匹配則用Equals
                .WhereIF(!input.Telephone.IsNullOrWhiteSpace(), t => t.Telephone.Contains(input.Telephone)) //如需要精確匹配則用Equals
                .WhereIF(!input.Fax.IsNullOrWhiteSpace(), t => t.Fax.Contains(input.Fax)) //如需要精確匹配則用Equals
                .WhereIF(!input.Contact.IsNullOrWhiteSpace(), t => t.Contact.Contains(input.Contact)) //如需要精確匹配則用Equals
                .WhereIF(!input.ContactPhone.IsNullOrWhiteSpace(), t => t.ContactPhone.Contains(input.ContactPhone)) //如需要精確匹配則用Equals
                .WhereIF(!input.ContactMobile.IsNullOrWhiteSpace(), t => t.ContactMobile.Contains(input.ContactMobile)) //如需要精確匹配則用Equals
                .WhereIF(!input.Email.IsNullOrWhiteSpace(), t => t.Email.Contains(input.Email)) //如需要精確匹配則用Equals
                .WhereIF(!input.QQ.IsNullOrWhiteSpace(), t => t.QQ.Contains(input.QQ)) //如需要精確匹配則用Equals
                .WhereIF(!input.Industry.IsNullOrWhiteSpace(), t => t.Industry.Contains(input.Industry)) //如需要精確匹配則用Equals
                .WhereIF(!input.BusinessScope.IsNullOrWhiteSpace(), t => t.BusinessScope.Contains(input.BusinessScope)) //如需要精確匹配則用Equals
                .WhereIF(!input.Brand.IsNullOrWhiteSpace(), t => t.Brand.Contains(input.Brand)) //如需要精確匹配則用Equals
                .WhereIF(!input.PrimaryClient.IsNullOrWhiteSpace(), t => t.PrimaryClient.Contains(input.PrimaryClient)) //如需要精確匹配則用Equals
                .WhereIF(!input.PrimaryBusiness.IsNullOrWhiteSpace(), t => t.PrimaryBusiness.Contains(input.PrimaryBusiness)) //如需要精確匹配則用Equals
                                                                                                                              //註冊資金區間查詢
               .WhereIF(input.RegisterCapitalStart.HasValue, s => s.RegisterCapital >= input.RegisterCapitalStart.Value)
               .WhereIF(input.RegisterCapitalEnd.HasValue, s => s.RegisterCapital <= input.RegisterCapitalEnd.Value)
               //營業額區間查詢
               .WhereIF(input.TurnOverStart.HasValue, s => s.TurnOver >= input.TurnOverStart.Value)
               .WhereIF(input.TurnOverEnd.HasValue, s => s.TurnOver <= input.TurnOverEnd.Value)
                .WhereIF(!input.LicenseNo.IsNullOrWhiteSpace(), t => t.LicenseNo.Contains(input.LicenseNo)) //如需要精確匹配則用Equals
                .WhereIF(!input.Bank.IsNullOrWhiteSpace(), t => t.Bank.Contains(input.Bank)) //如需要精確匹配則用Equals
                .WhereIF(!input.BankAccount.IsNullOrWhiteSpace(), t => t.BankAccount.Contains(input.BankAccount)) //如需要精確匹配則用Equals
                .WhereIF(!input.LocalTaxNo.IsNullOrWhiteSpace(), t => t.LocalTaxNo.Contains(input.LocalTaxNo)) //如需要精確匹配則用Equals
                .WhereIF(!input.NationalTaxNo.IsNullOrWhiteSpace(), t => t.NationalTaxNo.Contains(input.NationalTaxNo)) //如需要精確匹配則用Equals
                .WhereIF(!input.LegalMan.IsNullOrWhiteSpace(), t => t.LegalMan.Contains(input.LegalMan)) //如需要精確匹配則用Equals
                .WhereIF(!input.LegalTelephone.IsNullOrWhiteSpace(), t => t.LegalTelephone.Contains(input.LegalTelephone)) //如需要精確匹配則用Equals
                .WhereIF(!input.LegalMobile.IsNullOrWhiteSpace(), t => t.LegalMobile.Contains(input.LegalMobile)) //如需要精確匹配則用Equals
                .WhereIF(!input.Source.IsNullOrWhiteSpace(), t => t.Source.Contains(input.Source)) //如需要精確匹配則用Equals
                .WhereIF(!input.WebSite.IsNullOrWhiteSpace(), t => t.WebSite.Contains(input.WebSite)) //如需要精確匹配則用Equals
                .WhereIF(!input.CompanyPictureGUID.IsNullOrWhiteSpace(), t => t.CompanyPictureGUID.Contains(input.CompanyPictureGUID)) //如需要精確匹配則用Equals
                .WhereIF(!input.CustomerType.IsNullOrWhiteSpace(), t => t.CustomerType.Contains(input.CustomerType)) //如需要精確匹配則用Equals
                .WhereIF(!input.Grade.IsNullOrWhiteSpace(), t => t.Grade.Contains(input.Grade)) //如需要精確匹配則用Equals
                .WhereIF(!input.CreditStatus.IsNullOrWhiteSpace(), t => t.CreditStatus.Contains(input.CreditStatus)) //如需要精確匹配則用Equals
                .WhereIF(!input.Importance.IsNullOrWhiteSpace(), t => t.Importance.Contains(input.Importance)) //如需要精確匹配則用Equals
                .WhereIF(input.IsPublic.HasValue, t => t.IsPublic == input.IsPublic) //如需要精確匹配則用Equals
                .WhereIF(input.Satisfaction.HasValue, t => t.Satisfaction == input.Satisfaction) //如需要精確匹配則用Equals
                .WhereIF(!input.Note.IsNullOrWhiteSpace(), t => t.Note.Contains(input.Note)) //如需要精確匹配則用Equals
                .WhereIF(input.TransactionCount.HasValue, t => t.TransactionCount == input.TransactionCount) //如需要精確匹配則用Equals
              
                //交易金額區間查詢
               .WhereIF(input.TransactionTotalStart.HasValue, s => s.TransactionTotal >= input.TransactionTotalStart.Value)
               .WhereIF(input.TransactionTotalEnd.HasValue, s => s.TransactionTotal <= input.TransactionTotalEnd.Value)
               //首次交易時間區間查詢
               .WhereIF(input.TransactionFirstDayStart.HasValue, s => s.TransactionFirstDay >= input.TransactionFirstDayStart.Value)
               .WhereIF(input.TransactionFirstDayEnd.HasValue, s => s.TransactionFirstDay <= input.TransactionFirstDayEnd.Value)
               //最近交易時間區間查詢
               .WhereIF(input.TransactionLastDayStart.HasValue, s => s.TransactionLastDay >= input.TransactionLastDayStart.Value)
               .WhereIF(input.TransactionLastDayEnd.HasValue, s => s.TransactionLastDay <= input.TransactionLastDayEnd.Value)
               //最近聯繫日期區間查詢
               .WhereIF(input.LastContactDateStart.HasValue, s => s.LastContactDate >= input.LastContactDateStart.Value)
               .WhereIF(input.LastContactDateEnd.HasValue, s => s.LastContactDate <= input.LastContactDateEnd.Value)
                                                                                                      
               //創建時間區間查詢
               .WhereIF(input.CreateTimeStart.HasValue, s => s.CreateTime >= input.CreateTimeStart.Value)
               .WhereIF(input.CreateTimeEnd.HasValue, s => s.CreateTime <= input.CreateTimeEnd.Value)   
               //編輯時間區間查詢
               .WhereIF(input.EditTimeStart.HasValue, s => s.EditTime >= input.EditTimeStart.Value)
               .WhereIF(input.EditTimeEnd.HasValue, s => s.EditTime <= input.EditTimeEnd.Value)

               .WhereIF(!input.Stage.IsNullOrWhiteSpace(), t => t.Stage.Contains(input.Stage)) //如需要精確匹配則用Equals
               .WhereIF(!input.Status.IsNullOrWhiteSpace(), s => s.Status == input.Status)
               .WhereIF(!input.Creator.IsNullOrWhiteSpace(), t => t.Creator.Contains(input.Creator)) //如需要精確匹配則用Equals
               .WhereIF(!input.Editor.IsNullOrWhiteSpace(), t => t.Editor.Contains(input.Editor)) //如需要精確匹配則用Equals
               .WhereIF(input.Deleted.HasValue, s => s.Deleted == input.Deleted)
               .WhereIF(!input.Dept_ID.IsNullOrWhiteSpace(), t => t.Dept_ID.Contains(input.Dept_ID)) //如需要精確匹配則用Equals
               .WhereIF(!input.Company_ID.IsNullOrWhiteSpace(), t => t.Company_ID.Contains(input.Company_ID)) //如需要精確匹配則用Equals
               .WhereIF(!input.MarkColor.IsNullOrWhiteSpace(), t => t.MarkColor.Contains(input.MarkColor)) //如需要精確匹配則用Equals
               .WhereIF(!input.ShareUsers.IsNullOrWhiteSpace(), t => t.ShareUsers.Contains(input.ShareUsers)) //如需要精確匹配則用Equals
               ;

            return query;
        }

有了這個豐富條件的處理,我們就可以在前端進行屬性賦值就可以了,簡單的調用後端通用的介面查詢即可。

//構建分頁的條件和查詢條件
pagerDto = new CustomerPagedDto(this.winGridViewPager1.PagerInfo)
{
    //添加所需條件
    NameOrCode = this.txtCustomerNo.Text.Trim(),
    Deleted = 0
};

查詢獲得介面數據處理如下代碼所示。

var result = await BLLFactory<ICustomerService>.Instance.GetListAsync(pagerDto);
return result;

在分頁列表中展示獲得的記錄詳細信息如下代碼所示。

/// <summary>
/// 綁定列表數據
/// </summary>
private async void BindData()
{
    //entity
    this.winGridViewPager1.DisplayColumns = displayColumns;
    this.winGridViewPager1.ColumnNameAlias = await BLLFactory<ICustomerService>.Instance.GetColumnNameAlias();//欄位列顯示名稱轉義

    //獲取分頁數據列表
    var result = await GetData();

    //設置所有記錄數和列表數據源
    this.winGridViewPager1.PagerInfo.RecordCount = result.TotalCount; //需先於DataSource的賦值,更新分頁信息
    this.winGridViewPager1.DataSource = result.Items;
    this.winGridViewPager1.PrintTitle = "客戶信息列表";
}

 

3、對於多種屬性、狀態條件的統一處理

我在之前介紹過的CRM系統主界面中,關於客戶關係信息的展示的時候,是通過一個複雜的樹形列表來承載不同屬性來進行快速的查詢,如下界面所示。

這些樹形列表的屬性信息,在SqlSugar開發框架中,我們統一進行生成,首先定義一個通用的承載對象,如下類所示。

/// <summary>
/// 對CRM的業務數據進行統計的一個公共類
/// </summary>
public class CrmStaticsDto
{
    /// <summary>
    /// 節點顯示名稱
    /// </summary>
    public string Label { get; set; }

    /// <summary>
    /// 屬性名稱
    /// </summary>
    public string TypeName { get; set; }

    /// <summary>
    /// 數量
    /// </summary>
    public long Count { get; set; }

    /// <summary>
    /// 業務分類
    /// </summary>
    public string Category { get; set; }

    /// <summary>
    /// 記錄的日期開始
    /// </summary>
    public DateTime? DateStart { get; set; }
    /// <summary>
    /// 記錄的日期結束
    /// </summary>
    public DateTime? DateEnd { get; set; }

    /// <summary>
    /// 創建人信息
    /// </summary>
    public CListItem Creator { get; set; }

    /// <summary>
    /// 子節點集合
    /// </summary>
    public List<CrmStaticsDto> children { get; set; } = new List<CrmStaticsDto>();
}

這個類似一個嵌套的集合,通過children進行添加更多的子集記錄。

後端提供一個獲取統計信息的樹形列表的方法,如下定義所示。

        /// <summary>
        /// 獲取列表統計信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<CrmStaticsDto>> GetStatics(string compnayId)
{
................
}

但我們為它添加各種屬性的時候,設置相關的節點文本、類別信息即可。

    //所有記錄
    var allNode = new CrmStaticsDto()
    {
        Label = "所有記錄"
    };
    list.Add(allNode);

    var propertyNode = new CrmStaticsDto()
    {
        Label = "客戶屬性分類"
    };
    list.Add(propertyNode);


    var typeName = "客戶狀態";
    var count = await baseQuery.Clone().CountAsync();//Clone()避免進行多次查詢時,可能會出現結果不正確的問題
    var statusNode = new CrmStaticsDto()
    {
        Label = $"{typeName}({count})",
        Count = count,
        TypeName = typeName
    };
    var dict = await dictDataService.FindByDictType(typeName);
    foreach (var info in dict)
    {
        var value = info.Value;
        var subCount = baseQuery.Clone().Where(s => s.Status == value).Count();
        statusNode.children.Add(new CrmStaticsDto()
        {
            Label = $"{info.Name}({subCount})",
            Count = subCount,
            Category = info.Value,
            TypeName = typeName
        });
    }
    propertyNode.children.Add(statusNode);

這樣我們在前端的WInform界面中展示樹形列表的時候,就會變得非常簡單,通過一個遞歸的函數就可以添加相關的節點信息了,如下代碼所示。

private async void InitTree()
{
    this.treeView1.BeginUpdate();
    this.treeView1.Nodes.Clear();

    //獲取所有的統計列表
    var staticsList = await BLLFactory<ICustomerService>.Instance.GetStatics(this.SelectedCompanyID);
    await AddTreeData(staticsList, null);

    //this.treeView1.ExpandAll();
    this.treeView1.EndUpdate();
}

private async Task AddTreeData(List<CrmStaticsDto> staticsList, TreeNode parentNode = null)
{
    var i = 0;
    if (staticsList != null)
    {
        foreach (var info in staticsList)
        {
            var node = new TreeNode(info.Label, i, i);
            node.Tag = info;
            node.Text = info.Label;

            await AddTreeData(info.children, node);

            if (parentNode == null)
            {
                this.treeView1.Nodes.Add(node); //如果是頂級處理,則treeView1節點加入
            }
            else
            {
                parentNode.Nodes.Add(node); //如果是遞歸的,則加到父節點上
            }
        }
    }
}

以上就是對聯合多個表進行查詢以及樹形列表的條件展示的處理思路,系統能夠給大家一些參考思路。

專註於代碼生成工具、.Net/.NetCore 框架架構及軟體開發,以及各種Vue.js的前端技術應用。著有Winform開發框架/混合式開發框架、微信開發框架、Bootstrap開發框架、ABP開發框架、SqlSugar開發框架等框架產品。
  轉載請註明出處:撰寫人:伍華聰  http://www.iqidi.com 
    

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本篇專門扯一下有關 QCheckBox 組件的一個問題。老周不水字數,直接上程式,你看了就明白。 #include <QApplication> #include <QWidget> #include <QPushButton> #include <QCheckBox> #include <QVBo ...
  • # 2022版本IDEA+Maven+Tomcat的第一個程式(傻瓜教學) ​ 作為學習Javaweb的一個重要環節,如何實現在IDEA中利用Maven工具創建一個Javaweb程式模版並連接Tomcat發佈是非常重要的。我比較愚鈍(小白),而且自身電腦先前運行過spring或maven的程式,系統 ...
  • 歡迎來到本篇文章!通過上一篇什麼是 Spring?為什麼學它?的學習,我們知道了 Spring 的基本概念,知道什麼是 Spring,以及為什麼學習 Spring。今天,這篇就來說說 Spring 中的核心概念之一 IoC。 ...
  • 本次主要介紹golang中的標準庫`bytes`,基本上參考了 [位元組 | bytes](https://cloud.tencent.com/developer/section/1140520) 、[Golang標準庫——bytes](https://www.jianshu.com/p/e6f7f2 ...
  • ![線程各屬性縱覽](https://img2023.cnblogs.com/blog/1220983/202306/1220983-20230603114109107-477345835.png) 如上圖所示,線程有四個屬性: - 線程ID - 線程名稱 - 守護線程 - 線程優先順序 ### 1. ...
  • # 圖片介面JWT鑒權實現 # 前言 之前做了個返回圖片鏈接的介面,然後沒做授權,然後今天鍵盤到了,也是用JWT來做介面的許可權控制。 然後JTW網上已經有很多文章來說怎麼用了,這裡就不做多的解釋了,如果不懂的可以參考下列鏈接的 文章。 圖片介面文章:[還在愁個人博客沒有圖片放?](https://w ...
  • 以MySQL資料庫為例 # 一. 安裝 NuGet搜索Dapper.Lite並安裝最新版本。 ![](https://img2023.cnblogs.com/blog/174862/202306/174862-20230602155913303-757935399.jpg) NuGet搜索MySql ...
  • 從按鈕、文本框到下拉框、列表框,WPF提供了一系列常用控制項,每個控制項都有自己獨特的特性和用途。通過靈活的佈局容器,如網格、堆棧面板和換行面板,我們可以將這些控制項組合在一起,實現複雜的界面佈局。而通過樣式和模板,我們可以輕鬆地定製控制項的外觀和行為,以符合我們的設計需求。本篇記錄WPF入門需要瞭解的樣式... ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...