创建对于用户sa失败,sa无法映射到数据库_无法使用特殊主体sa-CSDN博客

mikel阅读(190)

来源: 创建对于用户sa失败,sa无法映射到数据库_无法使用特殊主体sa-CSDN博客

sa无法映射到数据库

在给SQL server中的用户”sa”映射到一个数据库的时候,报错:
创建 对于 用户”sa”失败
执行T-SQL语句或批处理时发生了异常。
无法使用特殊主体“sa”

解决方法:

(你要设置的)数据库–属性–文件–所用者设为Sa,回到用户映射查看,已勾选上.

还有一些情况

1)将登录方式设为”混合认证”(右击服务器->选择”安全性”->点选”Sql Server”和Windows身份认证模式)

2)设置sa账户 数据库->安全性(与上面的不是同一个,这个不用右击)->登录名->sa账户->设置密码->用户映射->映射到你的数据库

3)重启服务Sql server就可以了.

 

无法使用特殊主体’sa’

1)将登录方式设为”混合认证”(右击服务器->选择”安全性”->点选”Sql Server”和Windows身份认证模式)

2)启用了数据库的混合身份验证。
3)设置sa账户(数据库->安全性(与上面的不是同一个,这个不用右击)->登录名->sa账户->设置密码->用户映射->映射到你的数据库
3)重启服务Sql server.(net stop msSQLServer)

AI Agent技术的最新进展与改变世界的典型项目巡礼 - 汀、人工智能 - 博客园

mikel阅读(202)

来源: AI Agent技术的最新进展与改变世界的典型项目巡礼 – 汀、人工智能 – 博客园

1. AI Agent 技术发展以及典型项目

1.0 前 AI Agent 时代

在学术探索的浩瀚星空中,机器人技术领域的璀璨明珠莫过于Agent技术的深入研究,这一领域历来是创新与突破的温床。回溯至大模型浪潮兴起之前,Agent技术的辉煌篇章便已悄然铺展,诸如Alphago这样的里程碑式案例,以其卓越的环境感知、精准决策与高效行动能力,生动诠释了Agent技术的闭环魅力。同时,DeepMind的Agent57在强化学习领域的游戏挑战中崭露头角,而随后问世的Gato则展现了更为广泛的适用性,乃至OpenAI在“躲猫猫”游戏中展现的多智能体协作,无不预示着Agent技术的无限潜力。

展望未来,我们坚信Agent技术将成为驱动社会全面自动化的核心引擎。与以往侧重于结构化环境下通过既定算法实现的自动化不同,大模型的兴起为Agent技术赋予了前所未有的通用性与灵活性。这一转变,意味着Agent将能够跨越传统界限,深入人类脑力劳动的复杂长尾领域,从体力到脑力,全方位推进自动化的深度与广度。

大模型与Agent技术的融合,正引领我们步入一个全面自动化的新纪元。大模型作为知识海洋中的自主学习者,为Agent提供了前所未有的智慧源泉,激发了其快速发展的新动能。当前,尽管我们仍处于这一变革的初期,Agent技术更多以实验性、探索性的面貌呈现,但展望未来,其发展前景之广阔,变化速度之迅猛,或将超乎所有人的预料。随着技术的日新月异,我们或许会发现,所谓的“天花板”不过是通往更高境界的阶梯,而Agent技术的极限,正等待着我们共同去探索与定义。

1.1 AI等级划分

基于Agent(智能体)能力的AI等级划分,可以借鉴类似自动驾驶级别的划分方式,将AI智能体的能力从低到高进行分级。以下是一个简化的AI Agent能力划分描述:

AI Agent能力划分:

  • L0 – 没有人工智能
    在这一级别,Agent并不具备人工智能特性,只能执行预定或固定的任务,没有感知、决策或学习的能力。
  • L1 – 规则符号智能
    Agent开始具备基于规则的决策能力,能够根据预设的规则和符号进行简单的判断和执行。这种智能体通常只能处理特定情境下的任务,且缺乏灵活性和适应性。
  • L2 – 推理决策智能
    Agent能够利用逻辑推理能力来解决问题,不再仅仅依赖于预设的规则。它能够根据当前的环境信息和目标,进行一定程度的推理和决策,以选择最合适的行动方案。
  • L3 – 记忆反思智能
    在L3级别,Agent不仅具备推理决策能力,还开始拥有记忆和反思的能力。它能够记住过去的经验和教训,并在未来的决策中加以利用。这种智能体能够自我优化和改进,以适应不断变化的环境和任务。
  • L4 – 自主学习智能
    自主学习是L4级别Agent的主要特征。它能够自主地从数据中学习新知识和技能,无需人类的明确指导。这种智能体能够处理更复杂的问题,并在面对新情境时展现出更强的适应性和创造力。
  • L5 – 个性群体智能
    在最高级别,Agent不仅具备高度自主的学习和决策能力,还展现出个性化的特征。它能够根据自身的特点和偏好来执行任务,并与其他Agent进行协作和沟通。此外,L5级别的Agent还能够理解和适应人类社会的复杂性和多样性,与人类实现更加紧密和自然的交互。
  • AI 等级划分

  • AI apps building blocks

1.2 Prompt 工程

  • 通过描述角色技能、任务关键词、任务目标及任务背景,告知大模型需要输出的格式,并调用大模型进行输出

为了将 LLM 的能力发挥到极致,发展出了多种 prompt 工程

  • 角色扮演
  • 零样本分析
  • 少样本分析

在大模型初露锋芒之际,业界掀起了一股“Prompt工程”的热潮,将这一先进技术视为一种创新的编程范式加以探索。从业者们巧妙地将大模型转化为高度可定制的“智能工具”,通过精心构建的角色设定、技能描述、任务关键词的精准提炼、目标导向的明确阐述,以及详尽的任务背景铺设,构建起与模型沟通的桥梁。这一系列精心设计的指令,不仅界定了大模型需完成的任务范畴,还细化了输出结果的格式要求,随后通过直接调用大模型,实现知识的生成与输出的无缝衔接。

这一过程,被业界形象地称为“工具模式”,它深刻体现了大模型作为高级认知工具的价值所在。在此模式下,大模型不再仅仅是静态的数据处理器,而是转变为能够根据用户意图灵活应变、高效执行复杂任务的智能助手。这种将大模型工具化的探索,不仅极大地拓宽了技术的应用边界,也为人工智能领域的研究与实践开辟了新的思路与方向。

案例:15000 字符的 prompt 工程,扮演人类导师

https://github.com/JushBJJ/Mr.-Ranedeer-AI-Tutor

刚兴趣的同学可以用自己尝试一下:https://chat.openai.com/share/53b38605-68e5-4922-81fe-e4588fb28d8a

prompt 强化了 LLM 的能力,但以下的问题依然无法解决:

  • 不能及时更新知识
  • 上下文有限等等为了解决以上的问题,人们又发展出了很多的方法

1.2.1 Prompt 外挂 – RAG(Retrieval Augmented Generation)

  • 引入向量数据库
  • 数据索引进入向量数据库
  • 召回数据
  • 在提交给 LLM 做提示词工程

1.2.2 分而治之 – 古老的思想依然有效

  • 解决 context 不够的问题
  • 拆分成小段,分别摘要

1.2.3 step-by-step

  1. 思维链(Chain of Thought,CoT):要求模型展示其思考过程,而非仅给出答案
  2. 思维树(Tree of Thought,ToT):它会根据当前的问题分解出多个可能,然后每一个树节点就是父节点的一个子问题,逐层扩散,遍布整个解空间,一些节点就直接会发现不合适而终止掉,达到了有效剪枝的作用
  3. 思维图(Graph of Tree,GoT):基于思维树,既可以分解,也可以合并
    ……
  • 思维链(Chain of Thought, CoT)的深化

思维链的引入,标志着人工智能模型解答问题方式的重大转变。它强调模型需展现其内在的逻辑推理过程,而非仅仅呈现最终答案。这一过程可通过双轨并行实现:一是详尽阐述法,即模型被要求逐步、细致地展示其思考轨迹,确保每一步推理的透明度与逻辑性;二是范例引导法,通过提供包含完整思考路径的示例问题与答案,引导模型在面临新问题时模仿此过程,循序渐进地推导答案。随着实践的深入,我们进一步探索了CoT的潜力,发现当单一思维链遭遇障碍时,通过发散性思考,即CoT-SC(Chain of Thought with Strategic Convergence),模型能尝试多种解题路径,并通过投票机制筛选出最优解,从而增强了解的鲁棒性与多样性。

  • 思维树(Tree of Thought, ToT)的萌芽

面对CoT-SC在某些复杂问题(如24点游戏)上的局限性,我们转而探索思维树的构建。ToT策略将问题视为一个根系庞大的树木,其主干代表核心问题,而每一分支则是对该问题的不同分解路径。每个节点代表一个子问题,随着树的层层展开,解空间被细致划分,同时,不合适的分支被有效剪除,以优化搜索效率。然而,ToT在处理需要高度整合子问题结果的任务(如排序算法中的合并步骤)时仍显不足。

  • 思维图(Graph of Tree, GoT)的革新

为解决ToT的整合难题,思维图应运而生。GoT不仅继承了ToT的分解能力,更增添了灵活的合并机制,使得模型能够在复杂问题中自由穿梭于分解与整合之间,构建出既全面又精确的解决方案图。这一创新,标志着AI在复杂问题求解能力上的又一飞跃。

  • 累计推理:迈向新高度的探索

清华姚期智团队在思维推理领域取得了突破性进展,提出了累计推理方法。该方法在解决24点问题上已展现出高达98%的成功率,树立了新的技术标杆。其核心理念与主流Agent的实现方式相契合,强调通用性与实用性。累计推理首先孕育一个初步假设,随后通过不断验证与迭代,逐步构建并完善推理图。每个新节点都建立在稳固的已有基础上,通过发散、合并或修正,直至达成最终目标状态。这一过程不仅增强了推理的完备性,还赋予了模型前所未有的灵活性,为人工智能在更广泛领域的应用开辟了新的可能性。

1.2.4 基于反馈的 ReACT-Synergizing Reasoning and Acting

上述的讨论主要是任务分解和组合,他们尽管强大,却不能与外界进行互动,这就不得不讲到反馈机制了。

ReACT机制的核心在于将推理和行动紧密结合,使语言模型能够交替地产生推理路径(Thought)和文本动作(Action),以解决不同的语言推理和决策任务。具体来说,ReACT通过以下几个步骤实现这一目标:

  • 推理路径生成:模型首先基于当前的环境或上下文生成推理路径(Thought),这些推理路径包含了对问题或任务的逐步分析和理解。
  • 文本动作生成:在推理路径的指导下,模型生成文本动作(Action),这些动作可以是查询外部数据源、执行特定操作或生成最终答案等。
  • 环境交互与反馈:文本动作被发送到外部环境或数据源,以获取新的观测值(Observation)。这些观测值用于更新模型的内部状态,并作为后续推理和行动的基础。
  • 循环迭代:上述过程不断循环迭代,直到达到任务目标或满足某个终止条件

1.2.5 Reflexion

  • 背景与动机

传统的强化学习方法在训练大型语言模型时面临诸多挑战,如需要大量的训练样本和昂贵的模型微调成本。此外,传统的标量或向量奖励信号往往难以准确反映智能体在执行任务过程中的具体表现。Reflexion方法通过引入语言反馈机制,旨在解决这些问题,使语言智能体能够快速有效地从错误经验中学习。

  • 核心原理

Reflexion方法的核心在于将传统强化学习中的奖励信号转化为语言反馈信号(Verbal Reinforcement),并将其作为附加的上下文信息嵌入到大型语言模型中。具体来说,Reflexion框架包含以下几个关键组件:

  • Actor:由大型语言模型(LLM)担任,主要负责基于当前环境生成下一步的动作。
  • Evaluator:用于评估Actor生成结果的质量,类似于强化学习中的奖励函数。Evaluator将生成的轨迹作为输入,计算在给定任务上下文中的奖励分数。
  • Self-Reflexion:自我反思模块,也由LLM担任。该模块负责分析Actor的执行结果和Evaluator的奖励信号,生成具体且详细的语言反馈信号。这些反馈信号会储存在Memory中,以便在未来的决策中提供参考。
  • Memory:提供短期记忆和长期记忆功能。短期记忆存储当前实验中的上下文信息,而长期记忆则存储Self-Reflexion模块生成的反思结果。
  • 执行过程

Reflexion的执行过程是一个迭代过程,包括Actor生成动作、Evaluator评估动作、Self-Reflexion生成反思并存储结果等步骤。通过不断重复这个过程,智能体能够逐渐从错误经验中学习,并在未来的任务中做出更好的决策。

2. AI Agent

  • 定义

在 LLM 语境下,Agent 可以理解为某种能自主理解、规划决策、执行复杂任务的智能体。Agent 并非 ChatGPT 升级版,它不仅告诉你 “如何做”,更会帮你去做。如果 CoPilot 是副驾驶,那么 Agent 就是主驾驶。

2.1 AI Agent 系统组成

  • Planning(规划):
    • 子目标和分解:AI Agents 能够将大型任务分解为较小的、可管理的子目标,以便高效的处理复杂任务
    • 反思和细化:Agents 可以对过去的行为进行自我批评和反省,从错误中吸取经验教训,并为接下来的行动进行分析、总结和提炼,这种反思和细化可以帮助 Agents 提高自身的智能和适应性,从而提高最终结果的质量
  • Memory(记忆):
    • 短期记忆:所有上下文学习都是依赖模型的短期记忆能力进行的
    • 长期记忆:这种设计使得 AI Agents 能够长期保存和调用无限信息的能力,一般通过外部载体存储和快速检索来实现
  • Tool use(工具使用):
    • AI Agents 可以学习如何调用外部 API,以获取模型权重中缺少的额外信息,这些信息通常在预训练后很难更改,包括当前信息、代码执行能力、对专有信息源的访问等

2.2 Agent 项目(单/多智能体)

多智能体系统相较于单智能体系统(如AutoGPT)在多个方面展现出显著的优势,这些优势使得多智能体在处理复杂任务时更为高效、灵活和稳定。

  1. 信息处理与记忆容量优势
    • 多智能体优势:每个Agent在多智能体系统中仅需关注与自身角色或任务直接相关的信息,这种模块化的信息处理方式极大地减轻了单个智能体需要记忆和处理的数据量。因此,在面对长历史或复杂任务时,多智能体系统无需像单智能体那样维护庞大的记忆容量,降低了对模型序列长度的依赖,提高了系统的可扩展性和实用性。
    • 单智能体局限:单智能体如AutoGPT需要记住并处理所有历史信息以做出决策,这对模型的记忆容量和计算能力提出了极高的要求。在长历史任务中,这种需求可能导致性能瓶颈,限制了单智能体系统的应用范围。
  2. 稳定性与观点排除
    • 多智能体优势:通过角色扮演机制,多智能体系统能够模拟不同角色的视角和立场,从而有效排除某些偏见或错误观点的影响。这种机制使得系统输出更加客观、稳定,提高了决策质量。此外,不同智能体之间的交互还可以促进新想法的产生和验证,进一步增强了系统的创新性和适应性。
    • 单智能体局限:单智能体在执行多任务时,由于所有任务信息都混合在一起处理,容易受到各种因素的干扰,导致输出结果的不稳定。同时,单智能体难以有效区分和排除不同任务之间的潜在冲突或错误观点。
  3. 可拓展性与任务分解
    • 多智能体优势:多智能体系统通过分工协作的方式将复杂任务分解为多个相对简单的子任务,每个智能体专注于完成一个或几个子任务。这种任务分解策略不仅降低了单个智能体的处理难度,还提高了系统的整体效率和可拓展性。随着任务复杂度的增加,只需增加相应的智能体数量或调整智能体之间的协作策略即可应对。
    • 单智能体局限:单智能体在处理复杂任务时,通常需要依赖记忆节省策略(如token压缩、关键信息提取等)来减少输入给模型的context长度。然而,这些策略在极端情况下可能无法完全避免性能下降的风险,因为长序列处理仍然是大型语言模型面临的一个挑战。
  4. 并行探索与最优解选择
    • 多智能体优势:多智能体系统能够并行地探索多种解决方案,并通过比较和评估来选择最优解。这种并行探索机制不仅提高了问题求解的效率,还有助于发现更多潜在的优秀解。此外,不同智能体之间的探索结果可以相互借鉴和补充,形成更加全面的解决方案集合。
    • 单智能体局限:单智能体在探索解决方案时通常只能采用串行或有限的并行方式(如分支预测、多线程等),其效率受到模型处理能力和计算资源的限制。同时,由于单智能体缺乏多视角的评估机制,其选择的解决方案可能不是全局最优的。即使通过增加计算资源来提高并行度,也可能面临资源分配不均、协调困难等问题。

Auto-GPT

  • 简介:虽然内部设计为单个智能体,但其自我批判的逻辑被视为多智能体策略的简化版本。AutoGPT能够根据反馈调整其行为,体现了智能体自我改进的能力。
  • 应用:自动化任务执行、问题解决、基于指令的编程任务。

例子:https://twitter.com/SullyOmarr/status/1644750889432027136

  • created login/sign up page
  • styled it with bootstrap+ created flask api for login / logout
  • created a local json database
    Took ~10 minutes at a cost of $0.50

框架结构简单,但其设计理念具有重要意义,后续框架设计的思路都有这个的影子

  • 创建一个初始的计划,然后进入主循环
  • 系统会让模型判断在当前计划下该进行何种行动,接着会执行行动
  • 执行完毕后,结果会写入下一次循环中
  • 如此,每次决策都会基于之前的结果、记忆和计划,从而制定出新的行动方案
  • 优点:
    • 内存和上下文管理:与 AutoGen 一样,AutoGPT 在内存和上下文等领域也表现出色,为需要这些功能的 LLM 应用程序提供了优势。
  • 缺点:
    • 可视化构建器依赖性:应用程序设计依赖于可视化构建器,这可能会限制那些宁愿用代码定义设计的团队的灵活性。

AutoGen

  • 简介:AutoGen是一个开源框架,它通过多智能体对话来构建下一代大型语言模型应用。这个框架允许智能体通过对话相互协作,完成复杂任务,体现了智能体间的高度互动性和任务的灵活性。
  • 应用项目:AutoGen被设计为一个通用平台,可以应用于自动代码生成、复杂问题解决、自动化工作流程设计等领域。

论文链接:https://arxiv.org/abs/2308.08155

项目链接:https://github.com/microsoft/autogen


user_proxy (to assistant):

What date is today? Compare the year-to-date gain for META and TESLA.

--------------------------------------------------------------------------------
assistant (to user_proxy):

First, let's get the current date. We can do this using Python's built-in datetime module. Here is the Python code to get the current date:


import datetime

 Get the current date
current_date = datetime.date.today()

print("Today's date is:", current_date)


Next, we need to get the year-to-date (YTD) gain for META (Facebook) and TESLA. We can do this by using a financial data API such as Yahoo Finance. We will need to get the stock price at the start of the year and the current stock price, then calculate the percentage change.

However, as an AI, I'm unable to execute real-time web requests or access external APIs. I recommend using the `yfinance` library in Python to download the stock data. Here is an example of how you can do it:


import yfinance as yf

#Download stock data
meta_data = yf.download('META', start='2022-01-01', end=current_date)
tesla_data = yf.download('TSLA', start='2022-01-01', end=current_date)

#Calculate YTD gain
meta_ytd_gain = ((meta_data['Close'][-1] - meta_data['Close'][0]) / meta_data['Close'][0]) * 100
tesla_ytd_gain = ((tesla_data['Close'][-1] - tesla_data['Close'][0]) / tesla_data['Close'][0]) * 100

print("META YTD gain: ", meta_ytd_gain)
print("TESLA YTD gain: ", tesla_ytd_gain)


Please note that you need to install the `yfinance` library before running the above code. You can install it using pip:


pip install yfinance


Please replace `current_date` in the above code with the actual date you got from the first code.

--------------------------------------------------------------------------------

>>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...

>>>>>>>> EXECUTING CODE BLOCK 1 (inferred language is python)...
user_proxy (to assistant):

exitcode: 1 (execution failed)
Code output: 
Today's date is: 2023-10-17

Traceback (most recent call last):
  File "", line 4, in <module>
    meta_data = yf.download('META', start='2022-01-01', end=current_date)
NameError: name 'current_date' is not defined


--------------------------------------------------------------------------------
assistant (to user_proxy):

I apologize for the confusion. The `current_date` variable was defined in the first script and it's not available in the second script. Let's combine the two scripts into one so that the `current_date` variable can be used in the second part of the script. Here is the combined script:


import datetime
import yfinance as yf

#Get the current date
current_date = datetime.date.today()
print("Today's date is:", current_date)

#Download stock data
meta_data = yf.download('META', start='2022-01-01', end=current_date)
tesla_data = yf.download('TSLA', start='2022-01-01', end=current_date)

#Calculate YTD gain
meta_ytd_gain = ((meta_data['Close'][-1] - meta_data['Close'][0]) / meta_data['Close'][0]) * 100
tesla_ytd_gain = ((tesla_data['Close'][-1] - tesla_data['Close'][0]) / tesla_data['Close'][0]) * 100

print("META YTD gain: ", meta_ytd_gain)
print("TESLA YTD gain: ", tesla_ytd_gain)


Please run this script to get the current date and the year-to-date gain for META and TESLA.

--------------------------------------------------------------------------------

>>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...
user_proxy (to assistant):

exitcode: 0 (execution succeeded)
Code output: 
Today's date is: 2023-10-17

[*********************100%%**********************]  1 of 1 completed

[*********************100%%**********************]  1 of 1 completed
META YTD gain:  -5.136767947511282
TESLA YTD gain:  -36.50836025922416


--------------------------------------------------------------------------------
assistant (to user_proxy):

The current date is October 17, 2023. 

The year-to-date (YTD) gain for META (Facebook) is approximately -5.14%, indicating a decrease in value since the start of the year.

The YTD gain for TESLA is approximately -36.51%, indicating a significant decrease in value since the start of the year.

Please note that these values are based on the closing prices of the stocks and can vary slightly depending on the source of the data.

TERMINATE

--------------------------------------------------------------------------------

  • 优点:
    • 完善:AutoGen 拥有一个非常活跃的社区,非常适合寻求支持和协作的开发人员。
    • 可定制的代理:它还提供可定制的代理,可以集成 LLM、工具和人工反馈,使任务执行高度灵活。
  • 缺点:
    • 复杂性:这是一个相当复杂的框架,对于新用户来说可能是一个挑战,需要陡峭的学习曲线才能有效利用其功能。
    • 结构性较差:一些开发人员可能会发现 AutoGen 与其他框架相比结构性较差,这可能会影响实施的难易程度。

XAgent

项目链接:https://github.com/OpenBMB/XAgent

官方博文:https://blog.x-agent.net/blog/xagent/

  • 双循环机制
  • 外循环负责宏观规划,而内循环则负责细节的执行
  • 效果碾压 AutoGPT

  • 总结:
  1. 能力强大,但极耗 token,上述例子消耗了 10 刀 token
  2. 运行极慢,单次执行 30min
  3. 可扩展性比较强,可基于 ToolServer(基于智谱的另外一个项目 ToolBench)扩展自定义接口

OPENAI Assistants

MetaGPT

MetaGPT是一种创新的多智能体协作框架,其名字来源于“GPT-based Meta-Programming framework”,旨在通过分配不同的角色给生成式预训练变换器(GPTs),形成一个协作的软件实体以完成复杂任务。

  • 多智能体协作:MetaGPT的核心在于其多智能体协作的框架设计,每个GPT模型都被赋予特定的角色和任务,通过协作解决复杂问题,从而提高整体效率和性能。
  • 标准化操作程序(SOP):MetaGPT利用SOP来协调基于大语言模型(LLM)的多智能体系统,实现元编程技术,增强问题解决能力。
  • 高度可扩展性:随着任务复杂度的增加,可以通过添加更多的GPT模型来扩展MetaGPT系统的能力,使其能够适应不断变化的需求和环境。

论文链接:https://arxiv.org/abs/2308.00352

GitHub地址:https://github.com/geekan/MetaGPT

  • 优点:
    • 复杂的代理交互:MetaGPT 在支持代理之间的复杂交互方面表现出色,使其适用于复杂的多代理任务。
    • 丰富的库:它还附带一个丰富的预定义代理库,无需进行大量自定义开发即可实现一系列功能。
  • 缺点:
    • Asyncio 依赖性:严重依赖 asyncio,这对于网络密集型 I/O 来说可能很好,但与其他 python 原生并行处理方法相比,它有一些相当严重的限制。
    • 有限的通用性:MetaGPT 中的代理角色可能缺乏通用性,可能会限制其在需要高度可定制代理的场景中的使用。

适合人群:需要复杂的多代理交互和预定义复杂行为的项目。非常适合网络密集型异步操作和需要高级协作功能而无需大量定制的项目

AutoAgents

项目链接:https://github.com/Link-AGI/AutoAgents

AutoAgents的过程是分为两个关键阶段:Drafting 阶段和Execution阶段。Drafting阶段包括三个预定义agent(Planner、Agent Observer和Plan Observer)之间的协作讨论来综合定制的agent团队和适合输入问题的执行计划或任务。Execution阶段通过agent间协作和反馈完善计划,以及产生最终结果。论文提出self-refinement ,通过个体agent和协作进行自我完善通过多个agent进行细化,以提高agent的熟练程度并促进各agent之间的知识共享agents。为了促进合成团队中agents之间的具体分工,作者引入预定义的agent(Action Observer)以协助agents团队共享信息,协调行动,达成共识,适应环境。

crewAI

项目代码:https://github.com/joaomdmoura/crewAI
官网博文:https://docs.crewai.com/

  • 基于角色的Agent设计:使用特定的角色、目标和工具来定制Agents。
  • 自动化的Agents间委托:agents可以自主地委托任务并在彼此之间进行询问,从而提高问题解决效率。
  • 灵活的任务管理:使用可定制的工具定义任务,并将其动态分配给agents。
  • 流程驱动:目前仅支持顺序任务执行,但正在研究更复杂的流程,如协商一致和分层。

  • 优点:
    • 生产重点:CrewAI 的设计考虑到了生产用途,具有干净的代码和注重实际应用。
    • 代理委派:强调代理委派,允许在代理之间采用结构化的方法分配任务。
  • 缺点:
    • 重新委派限制:重新委派和使用外部代理的限制可能会限制分配和执行任务的灵活性。
    • 数据收集:收集匿名使用数据,这可能会引起某些团队的隐私问题。

更多项目

BabyAGI、CAMEL、DSPy、OpenAgents、Agents、AgentVerse、ChatDev、LangGraph

更多优质内容请关注公号:汀丶人工智能;会提供一些相关的资源和优质文章,免费获取阅读。

算法金 | 时间序列预测真的需要深度学习模型吗?是的,我需要。不,你不需要? - 算法金「全网同名」 - 博客园

mikel阅读(161)

来源: 算法金 | 时间序列预测真的需要深度学习模型吗?是的,我需要。不,你不需要? – 算法金「全网同名」 – 博客园

参考 论文:https://arxiv.org/abs/2101.02118

更多内容,见微*公号往期文章:

审稿人:拜托,请把模型时间序列去趋势!!

使用 Python 快速上手 LSTM 模型预测时间序列

1. 时间序列预测的重要性

时间序列预测,这玩意儿在数据分析界可是个香饽饽,尤其在电力、交通、空气质量这些领域里,预测得准,资源分配更合理,还能让相关部门提前做好准备。但深度学习这小子横空出世,开始抢传统统计学方法的风头。那么问题来了,时间序列预测非得用深度学习吗?咱们今天就来掰扯掰扯。

2. 传统时间序列预测模型

2.1 滚动平均(Moving Average, MA)

滚动平均,这招简单粗暴,就是把一段时间的数据一平均,把那些随机的波动给抹平,让长期趋势露个脸。这招对付那些没啥花头的时间序列挺管用。

2.2 向量自回归(Vector Autoregression, VAR)

VAR模型,这货是个多面手,能把多个时间序列的过去值拿来预测未来,把变量间的相互勾搭给看个清楚。这在经济学和金融领域里头,预测经济指标的相互作用,玩得风生水起。

2.3 自回归综合移动平均(AutoRegressive Integrated Moving Average, ARIMA)

ARIMA模型,这家伙把自回归、差分、移动平均三招合一,专门对付时间序列里的趋势和季节性。得先把序列给整平稳了,这样预测起来才靠谱。这模型在经济预测、销售预测、气象预测这些领域里头,玩得挺溜。

传统时间序列预测模型优点不少:

  1. 理论基础扎实:这些模型都是统计学出身,数学表达式和参数估计方法都明明白白。
  2. 解释性强:模型参数都有个说法,分析起来容易。
  3. 计算效率高:计算起来简单,处理大数据也不费劲。

不过,这些老方法在处理复杂的非线性关系和多变量交互效应时,就显得有点力不从心了。数据量大了,复杂度高了,深度学习方法就有机会上位了。

\

3. 深度学习模型

3.1 长短期记忆网络(Long Short-Term Memory, LSTM)

LSTM,这货是递归神经网络的升级版,门控机制一加,梯度消失问题就解决了。这货记性好,长时间序列里的信息记得牢,预测起来自然给力。

3.2 基于注意力的双阶段RNN(Dual-stage Attention-based Recurrent Neural Network, DARNN)

DARNN,这货加上了注意力机制,能挑出时间序列里的重要特征,预测精度就上去了。先提取特征,再用注意力机制和解码器预测,这招在不少预测任务里都挺灵。

3.3 Deep Global Local Forecaster (DeepGlo)

DeepGlo,这货把时间序列分成全局趋势和局部细节,分别建模,最后合并预测结果。这样不同尺度的特征都能照顾到,预测的准确性自然就高了。

3.4 时空融合转化器(Temporal Fusion Transformer, TFT)

TFT,这货用多头注意力机制和序列到序列的结构,处理时间序列的复杂关系。短期长期依赖关系都能搞定,处理复杂时空特征的数据,表现杠杠的。

3.5 DeepAR

DeepAR,这货基于自回归思想,序列到序列的建模方式,用过去的时间序列数据预测未来。这货能处理大规模高维数据,预测时还能考虑多个时间序列的相互影响,精度自然不低。

深度学习模型虽然在时间序列预测上挺能打,但复杂度高,计算成本也高,对数据量和计算资源要求也不小。所以选模型的时候,得综合考虑应用场景、数据特点和计算资源,挑最合适的。

4. GBRT模型的对比研究

4.1 研究背景

深度学习虽然火,但传统的机器学习方法,比如梯度提升回归树(GBRT),在实际应用中也挺能打。GBRT通过多个弱学习器组合,提升预测性能。研究人员把GBRT和深度学习模型比了比,看看谁更牛。

4.2 研究方法

这项研究把时间序列预测任务变成了窗口回归问题,对GBRT模型进行了特征设计和结构调整。就是把时间序列数据分成固定长度的窗口,每个窗口的数据用来预测下一个时间点的值。所有模型都用同样的数据集和评估指标,公平比较。

4.3 研究数据集

研究用了多个公开的时间序列数据集,涵盖能源消耗、交通流量、空气质量等领域,数据时间跨度和频率各异,全面评估模型表现。

4.4 评估指标

评估模型预测性能,用了均方误差(MSE)、均绝对误差(MAE)和对称平均绝对百分比误差(sMAPE)这些常用指标,全面衡量预测误差和稳定性。

研究结果,GBRT在多个数据集上的表现超过了所有评估的深度神经网络(DNN)模型。这说明,在时间序列预测任务中,传统机器学习方法有时候还挺能打的。

5. GBRT模型的优势

5.1 解释性高

GBRT模型,就像个明白事理的老江湖,每个决策点都清清楚楚,让人一看就懂。跟那些深不可测的深度学习模型比起来,它更接地气,容易让人信服。

5.2 计算效率高

说到计算效率,GBRT模型就像是轻功了得的侠客,行动迅速,不拖泥带水。深度学习模型可能还在慢吞吞地翻山越岭,它已经一溜烟跑到了目的地。

5.3 特征工程能力强

GBRT模型在特征工程上,就像个手艺高超的铁匠,能将普通的铁块锻造成锋利的宝剑。通过巧妙设计特征,它能够捕捉数据中的关键信息,让预测更加精准。

5.4 灵活性高

GBRT模型的灵活性,就像个能屈能伸的武林高手,无论面对什么样的对手,都能随机应变,调整自己的策略。通过调整参数,它能够适应各种不同的数据集和预测任务。

虽然GBRT模型在时间序列预测中表现出色,但它的威力还是得靠精心的特征工程和细致的参数调整来发挥。在实际应用中,得像打磨宝剑一样,细心调校,才能让它发挥出最大的威力。

6. 特征工程与损失函数的重要性

6.1 特征工程

特征工程,就像是给武林高手挑选武器,选对了,战斗力倍增。在时间序列预测中,通过提取时间、滚动统计、滞后等特征,能让模型更加敏锐地捕捉数据的脉动。

6.2 损失函数

损失函数,就像是武林比武的规则,决定了比试的胜负。选择合适的损失函数,能让模型在训练中更加精准地找到自己的不足,从而不断进步。

通过实验,我们发现GBRT模型在特征工程和损失函数的选择上,展现出了极高的灵活性和适应性。就像武林高手在比武中不断调整自己的招式,GBRT模型也能通过精细的特征设计和合理的损失函数选择,显著提升自己的预测性能。

7. 模型架构的创新

7.1 架构创新的难点

模型架构的创新,就像是武林中的绝世武功,听起来很酷,但练起来却难如登天。新架构往往需要大量的实验和调优,而且复杂性可能会带来更高的计算成本和更长的训练时间。

7.2 成功的架构创新实例

尽管如此,还是有些架构创新,像是武林中的奇遇,让人眼前一亮。比如LSTM的门控机制,就像是突然领悟了一门高深的内功心法,让模型在处理长时间依赖关系时更加得心应手。

7.3 特征工程和损失函数的优先性

研究表明,当特征工程和损失函数设置得当,架构创新带来的提升其实有限。这就像是武林中的基本功,只有基本功扎实了,才能让后续的招式发挥出更大的威力。

7.4 创新带来的风险

模型架构的创新,也伴随着一定的风险。新架构的复杂性可能会导致训练过程中的不稳定性,增加过拟合的风险,同时还可能需要更多的数据和计算资源。在实践中,如何平衡创新带来的潜在收益和这些风险,是一个需要仔细权衡的问题。

8. 多输出预测的局限性

8.1 多输出预测的基本方法

在时间序列预测中,把预测器包装成支持多输出的MultiOutputRegressor,就像是一箭双雕,提高了预测效率,同时还能捕捉不同时间序列之间的相互依赖。

8.2 存在的局限性

但多输出预测也有它的局限性。由于所有输出都共享同一个模型结构和参数设置,这就像是用同一把钥匙开所有的锁,可能无法充分适应每个时间序列的独特性,导致预测精度下降。

8.3 改进建议

为了克服这些局限,可以考虑在模型中增加更强的约束,就像是给每个锁配上一把专属的钥匙。通过引入分层模型结构,在顶层捕捉不同时间序列的共同特征,在底层分别建模每个时间序列的特有特征。

8.4 实验验证

研究表明,通过引入这些改进措施,多输出预测模型在多个时间序列预测任务中取得了显著提升。这就像是武林中的高手,通过不断的修炼和创新,最终达到了新的境界。

9. 实验结果

9.1 单变量时间序列预测

在单变量时间序列预测任务中,GBRT模型就像是一匹黑马,无论是有协变量还是没有协变量,都展现出了优越的性能。特别是在没有协变量的情况下,通过合理的特征设计,GBRT模型能够有效捕捉时间序列中的趋势和波动,预测结果优于大多数深度学习模型。

9.2 多变量时间序列预测

在多变量时间序列预测任务中,GBRT模型与LSTNet、DeepAR、DeepState、TFT等深度学习模型相比,就像是武林中的一场较量,GBRT模型在大多数数据集上都取得了更高的预测精度。这主要归功于GBRT模型在特征工程和参数调整上的灵活性,使其能够更好地适应不同的数据特点和预测任务。

9.3 有协变量的预测

在有协变量的预测任务中,GBRT模型就像是得到了神助攻,通过合理利用协变量信息,能够进一步提升预测精度。例如,在能源消耗预测任务中,通过引入天气数据和历史用电量作为协变量,GBRT模型能够更准确地预测未来的能源需求。

9.4 结果分析

总体来看,实验结果验证了GBRT模型在时间序列预测中的竞争力。尽管深度学习模型在某些特定任务中表现出色,但GBRT模型通过合理的特征设计和参数调整,在大多数情况下能够取得更高的预测精度和稳定性。

[ 抱个拳,总个结 ]

  • 时间序列预测,在多个领域里头,传统方法和深度学习方法各有千秋。
  • 传统时间序列预测模型,像MA、VAR和ARIMA,理论基础扎实,计算效率高,但在处理复杂的非线性关系和多变量交互效应方面,就显得有点力不从心。
  • 深度学习模型,如LSTM、DARNN、DeepGlo、TFT和DeepAR,自动学习数据中的复杂模式和特征,在多个预测任务中展示出强大的性能。
  • GBRT模型,在实验中表现优越,尤其在适当配置的情况下,能够超过许多最先进的深度学习模型。
  • 特征工程和损失函数,在机器学习中至关重要,合理的特征设计和损失函数选择能够显著提升模型性能。
  • 模型架构的创新带来的提升有限,优先关注特征工程和损失函数的优化更为重要。
  • 多输出预测方法存在局限性,通过合理的改进措施可以提升其性能。
  • 实验结果显示,GBRT模型在单变量和多变量时间序列预测中均表现出色,特别是在有协变量的情况下,优势更加明显。

更多内容,见微*公号往期文章:

审稿人:拜托,请把模型时间序列去趋势!!

使用 Python 快速上手 LSTM 模型预测时间序列

– 科研为国分忧,创新与民造福 –

日更时间紧任务急,难免有疏漏之处,还请大侠海涵内容仅供学习交流之用,部分素材来自网络,侵联删

记一次 .NET某网络边缘计算系统 卡死分析 - 一线码农 - 博客园

mikel阅读(208)

来源: 记一次 .NET某网络边缘计算系统 卡死分析 – 一线码农 – 博客园

一:背景

1. 讲故事

早就听说过有什么 网络边缘计算,这次还真给遇到了,有点意思,问了下 chatgpt 这是干嘛的 ?

网络边缘计算是一种计算模型,它将计算能力和数据存储位置从传统的集中式数据中心向网络边缘的用户设备、传感器和其他物联网设备移动。这种模型的目的是在接近数据生成源头的地方提供更快速的计算和数据处理能力,从而减少数据传输延迟并提高服务质量。网络边缘计算使得在设备本地进行数据处理和决策成为可能,同时也有助于减轻对中心数据中心的网络流量和负载。

看到.NET还有这样的应用场景还是挺欣慰的,接下来就来分析下这个dump到底是怎么回事?

二:WinDbg 分析

1. 为什么会卡死

不同程序的卡死有不同的分析方式,所以要先鉴别下程序的类型以及主线程的调用栈即可,参考如下:


0:000> !eeversion
5.0.721.25508
5.0.721.25508 @Commit: 556582d964cc21b82a88d7154e915076f6f9008e
Server mode with 64 gc heaps
SOS Version: 8.0.10.10501 retail build

0:000> k
 # Child-SP          RetAddr               Call Site
00 0000ffff`e0dddac0 0000fffd`c194c30c     libpthread_2_28!pthread_cond_wait+0x238
...
18 (Inline Function) --------`--------     libcoreclr!RunMain::$_0::operator()::{lambda(Param *)#1}::operator()+0x14c [/__w/1/s/src/coreclr/src/vm/assembly.cpp @ 1536] 
19 (Inline Function) --------`--------     libcoreclr!RunMain::$_0::operator()+0x188 [/__w/1/s/src/coreclr/src/vm/assembly.cpp @ 1538] 
1a 0000ffff`e0dde600 0000fffd`c153e860     libcoreclr!RunMain+0x298 [/__w/1/s/src/coreclr/src/vm/assembly.cpp @ 1538] 
...
20 0000ffff`e0dded10 0000fffd`c1bf7800     libhostpolicy!corehost_main+0xc0 [/root/runtime/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp @ 409] 
21 (Inline Function) --------`--------     libhostfxr!execute_app+0x2c0 [/root/runtime/src/installer/corehost/cli/fxr/fx_muxer.cpp @ 146] 
22 (Inline Function) --------`--------     libhostfxr!<unnamed-namespace>::read_config_and_execute+0x3b4 [/root/runtime/src/installer/corehost/cli/fxr/fx_muxer.cpp @ 520] 
23 0000ffff`e0ddeeb0 0000fffd`c1bf6840     libhostfxr!fx_muxer_t::handle_exec_host_command+0x57c [/root/runtime/src/installer/corehost/cli/fxr/fx_muxer.cpp @ 1001] 
24 0000ffff`e0ddf000 0000fffd`c1bf4090     libhostfxr!fx_muxer_t::execute+0x2ec
25 0000ffff`e0ddf130 0000aaad`c9e1d22c     libhostfxr!hostfxr_main_startupinfo+0xa0 [/root/runtime/src/installer/corehost/cli/fxr/hostfxr.cpp @ 50] 
26 0000ffff`e0ddf200 0000aaad`c9e1d468     dotnet!exe_start+0x36c [/root/runtime/src/installer/corehost/corehost.cpp @ 239] 
27 0000ffff`e0ddf370 0000fffd`c1c63fe0     dotnet!main+0x90 [/root/runtime/src/installer/corehost/corehost.cpp @ 302] 
28 0000ffff`e0ddf3b0 0000aaad`c9e13adc     libc_2_28!_libc_start_main+0xe0
29 0000ffff`e0ddf4e0 00000000`00000000     dotnet!start+0x34

从卦中的指标来看,这是一个 Linux 上部署的 Web网站,既然是网站的卡死,那就要关注各个线程都在做什么。

2. 线程都在干嘛

以我多年的分析经验,绝大多数都是由于 线程饥饿 或者说 线程池耗尽 导致的,首先我们看下线程池的情况。


0:000> !t
ThreadCount:      365
UnstartedThread:  0
BackgroundThread: 354
PendingThread:    0
DeadThread:       10
Hosted Runtime:   no
                                                                                                            Lock  
 DBG   ID     OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception
   0    1    31eaf 0000AAADF267C600  2020020 Preemptive  0000000000000000:0000000000000000 0000aaadf26634b0 -00001 Ukn 
...
 423  363    36d30 0000FFDDB4000B20  1020220 Preemptive  0000000000000000:0000000000000000 0000aaadf26634b0 -00001 Ukn (Threadpool Worker) 
 424  364    36d31 0000FFDDA8000B20  1020220 Preemptive  0000000000000000:0000000000000000 0000aaadf26634b0 -00001 Ukn (Threadpool Worker) 
 425  365    36d32 0000FFDDAC000B20  1020220 Preemptive  0000000000000000:0000000000000000 0000aaadf26634b0 -00001 Ukn (Threadpool Worker) 

0:000> !tp
Using the Portable thread pool.

CPU utilization:  9%
Workers Total:    252
Workers Running:  236
Workers Idle:     13
Worker Min Limit: 64
Worker Max Limit: 32767

Completion Total:   0
Completion Free:    0
Completion MaxFree: 128
Completion Current Limit: 0
Completion Min Limit:     64
Completion Max Limit:     1000

从卦中看当前有 365 个托管线程,这个算多吗?对于64core 来说,这个线程其实算是正常,训练营里的朋友都知道,server版的gc仅gc线程就有 64*2=128 个,接下来再看一个指标就是当前是否存在任务积压? 可以使用 !ext tpq 命令,参考输出如下:


0:000> !ext tpq
global work item queue________________________________

local per thread work items_____________________________________

从卦中看当前没有任务积压,这就有点反经验了。

3. 真的不是线程饥饿吗

最后一招比较彻底,就是看各个线程栈都在做什么,可以使用 ~*e !clrstack 命令。

这不看不知道,一看吓一跳,有 193 个线程在 Task.Result 上等待,这玩意太经典了,然后从上面的调用栈 UIUpdateTimer_Elapsed 来看,貌似是一个定时器导致的,接下来我就好奇这代码是怎么写的?

分析上面的代码之后,我发现它是和 Linux Shell 窗口进行命令交互,不知道为何 Shell 没有响应导致代码在这里卡死。

4. 为什么线程池没有积压

相信有很多朋友对这个反经验的东西很好奇为什么请求没有积压在线程池,其实这个考验的是你对 PortableThreadPool 的底层了解,这里我就简单说一下吧。

  1. 在 ThreadPool 中有一个 GateThread 线程是专门给线程池动态注入线程的,参考代码如下:

private static class GateThread
{
    private static void GateThreadStart()
    {
        while (true)
        {
            bool wasSignaledToWake = DelayEvent.WaitOne((int)delayHelper.GetNextDelay(tickCount));

            WorkerThread.MaybeAddWorkingWorker(threadPoolInstance);
        }
    }
}

  1. 一旦有人调用了 Task.Result 代码,内部会主动唤醒 DelayEvent 事件,告诉 GateThread 赶紧通过 MaybeAddWorkingWorker 方法给我注入新的线程,参考代码如下:

private bool SpinThenBlockingWait(int millisecondsTimeout, CancellationToken cancellationToken)
{
    bool flag3 = ThreadPool.NotifyThreadBlocked();

}
internal static bool NotifyThreadBlocked()
{
    if (UsePortableThreadPool)
    {
        return PortableThreadPool.ThreadPoolInstance.NotifyThreadBlocked();
    }
    return false;
}
public bool NotifyThreadBlocked()
{
    GateThread.Wake(this);
}

上面这种主动唤醒的机制是 C# 版 PortableThreadPool 做的优化来缓解线程饥饿的,这里有一个重点就是它只能缓解,换句话说如果上游太猛了还是会有请求积压的,但为什么这里没有积压呢? 很显然上游不猛呗,那如何眼见为实呢? 这就需要看 timer 的周期数即可,到当前的线程栈上给扒出来。


0:417> !DumpObj /d 0000ffee380757f8
Name:        System.Timers.Timer
MethodTable: 0000fffd4ab24030
EEClass:     0000fffd4ad6e140
Size:        88(0x58) bytes
File:        /home/user/env/dotnet/shared/Microsoft.NETCore.App/5.0.7/System.ComponentModel.TypeConverter.dll
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
0000fffd4c947498  400001c        8 ...ponentModel.ISite  0 instance 0000000000000000 _site
0000000000000000  400001d       10 ....EventHandlerList  0 instance 0000000000000000 _events
0000fffd479195d8  400001b       98        System.Object  0   static 0000000000000000 s_eventDisposed
0000fffd47926f60  400000e       40        System.Double  1 instance 3000.000000 _interval
0000fffd4791fb10  400000f       48       System.Boolean  1 instance                1 _enabled
0000fffd4791fb10  4000010       49       System.Boolean  1 instance                0 _initializing
0000fffd4791fb10  4000011       4a       System.Boolean  1 instance                0 _delayedEnable
0000fffd4ab241d8  4000012       18 ...apsedEventHandler  0 instance 0000ffee3807aae8 _onIntervalElapsed
0000fffd4791fb10  4000013       4b       System.Boolean  1 instance                1 _autoReset
0000fffd4c944ea0  4000014       20 ...SynchronizeInvoke  0 instance 0000000000000000 _synchronizingObject
0000fffd4791fb10  4000015       4c       System.Boolean  1 instance                0 _disposed
0000fffd49963e28  4000016       28 ...m.Threading.Timer  0 instance 0000ffee38098dc8 _timer
0000fffd48b90a30  4000017       30 ...ing.TimerCallback  0 instance 0000ffee3807aaa8 _callback
0000fffd479195d8  4000018       38        System.Object  0 instance 0000ffee38098db0 _cookie

从卦中看当前是 3s 为一个周期,这就能解释为什么线程池没有积压的底层原因了。

三:总结

这个卡死事故还是蛮好解决的,如果有一些经验直接用dotnet-counter也是能搞定的,重点在于这是一个 Linux的dump,同时又是 .NET上的一个很好玩的场景,故此分享出来。

值得推荐的.NET ORM框架 - 追逐时光者 - 博客园

mikel阅读(227)

来源: 值得推荐的.NET ORM框架 – 追逐时光者 – 博客园

前言:

最近有很多同学问我.NET方面有哪些好用的ORM框架,我觉得这方面的介绍网上应该会介绍的比较全面文章,于是我想搜一篇全面的介绍文章发给他们结果我发现网上说来说去基本上就是那几个,于是就有了这篇文章。该篇文章已收录到【DotNetGuide(C#/.NET/.NET Core学习、工作、面试指南)👉】GitHub知识库中欢迎大家前往订阅(有帮助的话别忘了给我一颗小星星⭐),假如大家有更好的ORM框架推荐可以前往GitHub仓库中留言💖!

什么是ORM?

ORM 是 Object Relational Mapping 的缩写,译为“对象关系映射”,是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。它解决了对象和关系型数据库之间的数据交互问题,ORM的作用是在关系型数据库和业务实体对象之间作一个映射,这样我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。

如何选择合适自己的ORM框架?

对于我们而言选择ORM框架的目的其实都是为了让我们的程序更好的操作数据库,提高开发编程效率和程序的维护拓展性。因此我们在为自己负责的项目选择合适的ORM框架的时候需要从项目的业务场景出发,选择最适合自己团队的ORM框架(注意没有完美的框架,适合团队的才是最好的)。以下是一些比较好用且优秀的.NET-ORM框架汇总,排名不分先后可供大家参考学习(假如您有更好的.NET相关ORM推荐请在文末留言,谢谢)。

EF/EF Core

Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术,EF Core 是适用于 .NET 的现代对象数据库映射器。它支持 LINQ 查询、更改跟踪、更新和架构迁移。EF Core 通过提供程序插件 API 与 SQL Server、Azure SQL 数据库、SQLite、Azure Cosmos DB、MySQL、PostgreSQL 和其他数据库一起使用。(微软官方出品)。

EF Core 可用作对象关系映射程序 (O/RM),这可以实现以下两点:

  • 使 .NET 开发人员能够使用 .NET 对象处理数据库。
  • 无需再像通常那样编写大部分数据访问代码。

官方文档教程:https://docs.microsoft.com/zh-cn/ef/

GitHub地址:https://github.com/dotnet/efcore

以下是EF/EF Core相关拓展程序包:

Dapper

Dapper是一个简单的.NET对象映射器,在速度方面具有”King of Micro ORM”的头衔,几乎与使用原始的ADO.NET数据读取器一样快。ORM是一个对象关系映射器,它负责数据库和编程语言之间的映射。Dapper通过扩展IDbConnection提供一些有用的扩展方法去查询您的数据库。
主要特点:高性能、易排查、易运维、灵活可控。

以下是Dapper相关拓展程序包:

  • Dapper-Extensions – Dapper Extensions 是一个小型ORM库,通过为您的 POCO 添加基本的 CRUD 操作(获取、插入、更新、删除)来补充Dapper。对于更高级的查询场景,Dapper Extensions 提供了一个谓词系统。这个库的目标是通过不需要任何属性或基类继承来保持你的 POCO 纯净。
  • Dapper-FluentMap – Dapper的扩展。
  • Dommel – Dapper的CRUD操作。
  • MicroOrm.Dapper.Repositories – Dapper的CRUD操作。

FreeSql

FreeSql 是一款功能强大的对象关系映射(O/RM)组件,支持 .NET Core 2.1+、.NET Framework 4.0+ 以及 Xamarin。
主要特点:
  • 支持 CodeFirst 模式,即便使用 Access 数据库也支持数据迁移;
  • 支持 DbFirst 模式,支持从数据库导入实体类,或使用实体类生成工具生成实体类;
  • 支持 深入的类型映射,比如 PgSql 的数组类型等;
  • 支持 丰富的表达式函数,以及灵活的自定义解析;
  • 支持 导航属性一对多、多对多贪婪加载,以及延时加载;
  • 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁;
  • 支持 MySql/SQLServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/ClickHouse/Access 等数据库;

官方文档地址:http://www.freesql.net/

GitHub地址:https://github.com/dotnetcore/FreeSql

SqlSugar

SqlSugar是一款老牌 .NET 开源ORM框架,支持.NET CORE 和 MySql、SqlServer、Sqlite、Oracle 、 postgresql 、达梦、人大金仓 数据库,具有EF NH的功能,比EF更人性化的语法,支持真实的批量操作,另外还有媲美Dapper的性能。

主要特点:简单易用、功能齐全、高性能、轻量级、服务齐全、支持全自动分表组件,SAAS分库,大数据处理的ORM。
官网地址:http://www.donet5.com

Chloe

Chloe 是一个轻量级的对象/关系映射(ORM)库。查询接口类似于 LINQ。您可以使用 Chloe.ORM 通过 lambda 查询 LINQ 之类的数据并执行任何操作(加入查询 | 组查询 | 聚合查询 | 插入 | 批量更新 | 批量删除)。

文档地址:https ://github.com/shuxinqin/Chloe/wiki

GitHub地址:https://github.com/shuxinqin/Chloe

nhibernate-core

 NHibernate 是一个成熟的开源对象关系映射器,适用于 .NET 框架。它被积极开发,功能齐全,并在数千个成功的项目中使用。

NHibernate社区网站 – https://nhibernate.info

GitHub地址:https://github.com/nhibernate/nhibernate-core

SmartSql

SmartSql = C# 中的 MyBatis + .NET Core+ 缓存(内存 | Redis)+ R/W 拆分 + PropertyChangedTrack +动态存储库 + InvokeSync + 诊断。

SmartSql 借鉴了 MyBatis 的思想,使用 XML 来管理 SQL ,并且提供了若干个筛选器标签来消除代码层面的各种 if/else 的判断分支。SmartSql将管理你的 SQL ,并且通过筛选标签来维护本来你在代码层面的各种条件判断,使你的代码更加优美。

主要特点:简洁、高效、高性能、扩展性、监控、渐进式开发!

PetaPoco

PetaPoco 是一个用于 .NET(4、4.5+、net standard 2.0+)和 Mono 的微型、快速、易于使用的 micro-ORM。由于 PetaPoco 所代表的简单性和易用性,它受到许多人的喜爱。PetaPoco 是首选的微 ORM,也是任何体面的开发人员工具包中必不可少的实用程序。
主要特点:
  • Dapper一样,它很快,因为它使用动态方法生成 (MSIL) 将列值分配给属性。
  • Massive一样,它现在也支持动态 Expandos。
  • ActiveRecord一样,它支持对象和数据库表之间的密切关系。
  • SubSonic一样,它支持使用 T4 模板生成 poco 类(仅限 V5)。
  • Massive一样,它以单个文件的形式提供,您可以轻松地将其添加到任何项目或编译(仅限 V5)。

linq2db

LINQ to DB 是最快的LINQ数据库访问库,在POCO对象和数据库之间提供了一个简单、轻量、快速且类型安全的层。
在架构上,它比 Dapper、Massive 或 PetaPoco 等微 ORM 高出一步,因为您使用 LINQ 表达式,而不是魔术字符串,同时在代码和数据库之间维护一个薄抽象层。您的查询由 C# 编译器检查并允许轻松重构。
但是,它不像 LINQ to SQL 或实体框架那么重。没有更改跟踪,因此您必须自己进行管理,但从积极的方面来说,您可以获得更多控制权并更快地访问您的数据。

文档地址:https://linq2db.github.io/ 

GitHub地址:https://github.com/linq2db/linq2db

RepoDb

 RepoDB是一个开源的.NET ORM库,它弥合了微ORM和完整ORM之间的差距。它帮助您简化在开发过程中何时使用基本操作和高级操作的切换。

主要特点:

  • 易于使用- 这些操作都作为您的 IDbConnection 对象的扩展方法实现。只要您的连接处于打开状态,就可以对您的数据库调用任何操作。
  • 高性能- 它缓存已经生成的编译表达式以供将来重用和执行。它了解您的架构以创建最佳的编译表达式 AOT。
  • 内存高效- 它提取并缓存您的对象属性、执行上下文、对象映射和 SQL 语句。它在整个转换和执行过程中重用它们。
  • 动态和混合- 它提供了成熟 ORM 的一些高级功能。它极大地帮助开发人员在开发过程中进行上下文切换时简化体验。
  • 开源软件——它是一个开源软件,并且永远是免费的。它旨在进一步改进 .NET 数据访问体验和解决方案,以及社区的集体思想。
  • 高质量- 它是一个高质量的微型 ORM,由 10K+ 真实单元和集成测试支持。它经过高度测试,并被生产环境中运行的各种关键系统使用。

GitHub地址:https://github.com/mikependon/RepoDB

ServiceStack.OrmLite

 OrmLite是一个快速、简单、类型化的.NET ORM,OrmLite 的目标是提供一个方便、DRY、无配置、与 RDBMS 无关的类型包装器,该包装器与 SQL 保持高度亲和性,公开直观的 API,生成可预测的 SQL 并干净地映射到断开连接和数据传输对象 (DTO) 友好、普通的旧C# 对象 (POCO)。这种方法更容易推理您的数据访问,从而清楚地知道什么 SQL 在什么时间执行,同时减轻意外行为、隐式 N+1 查询和重对象关系映射器 (ORM) 中普遍存在的泄漏数据访问。

文档地址:https://docs.servicestack.net/ormlite/

GitHub地址:https://github.com/ServiceStack/ServiceStack.OrmLite

SQLite-net

 简单、强大、跨平台的 SQLite 客户端和 .NET 的 ORM。

主要特点:

  • 非常容易与现有项目集成并在所有 .NET 平台上运行。

  • SQLite 上的瘦包装器,快速高效。(这个库不应该是您查询的性能瓶颈。)

  • 用于安全执行 CRUD 操作和查询(使用参数)并以强类型方式检索这些查询结果的非常简单的方法。

  • 与您的数据模型一起工作,而不会强迫您更改您的类。(包含一个小的反射驱动 ORM 层。)

GitHub地址:https://github.com/praeclarum/sqlite-net

Insight.Database

Insight.Database是一个用于 .NET 的快速、轻量级的 micro-orm。

GitHub地址:https://github.com/jonwagner/Insight.Database

cyqdata

 cyq.data是一个高性能且功能最强大的orm(支持.NET Core),支持Txt、Xml、Access、Sqlite、Mssql、Mysql、Oracle、Sybase、Postgres、DB2、Redis、MemCache。

GitHub地址:https://github.com/cyq1162/cyqdata

TinyORM

TinyORM是一个简单、快速且安全的微型.NET ORM。

Wiki地址:https://github.com/sdrapkin/SecurityDriven.TinyORM/wiki

GitHub地址:https://github.com/sdrapkin/SecurityDriven.TinyORM

querybuilder

SQL 查询构建器,用 c# 编写,帮助您轻松构建复杂的查询,支持 SqlServer、MySql、PostgreSql、Oracle、Sqlite 和 Firebird。

官网地址:https://sqlkata.com/

GitHub地址:https://github.com/sqlkata/querybuilder

一款利用人工智能将自然语言查询转换为 SQL 代码的互译工具 - SQL Translator - 追逐时光者 - 博客园

mikel阅读(191)

来源: 一款利用人工智能将自然语言查询转换为 SQL 代码的互译工具 – SQL Translator – 追逐时光者 – 博客园

前言

对于后端程序员来说,编写SQL代码是日常工作中不可或缺的一部分。然而,随着数据复杂性的增加,如何高效、准确地编写SQL查询成为了新的挑战。幸运的是,SQL Translator的出现为后端程序员提供了一个强大的工具,将自然语言查询转换为精确的SQL代码,极大地提高了工作效率。

SQL Translator介绍

SQL Translator是一款利用人工智能将自然语言查询转换为 SQL 代码的互译工具,它的主要目的是简化SQL查询的编写过程,让非专业的SQL用户、数据库管理员、数据分析师等能够以自然语言的形式输入查询,然后快速获得对应的SQL代码。此外,用户还可以将已有的SQL代码输入,获取易于理解的自然语言翻译,从而更直观地理解SQL代码的含义。

此项目基于MIT License协议开源、100%免费。

工具特性

  • 支持暗黑模式。
  • 支持大小写切换。
  • 支持复制到剪贴板。
  • 支持SQL语法高亮显示。
  • 支持查看查询历史。

本地项目部署

克隆项目到本地

git clone https://github.com/whoiskatrin/sql-translator.git

安装所需的软件包

cd sql-translator
npm install

生成应用程序

npm run build

在.env文件中输入您的OPENAI API的密钥

OPENAI_API_KEY=$YOUR_API_KEY

启动开发服务器

npm start

在线效果演示

创建一个用户表

插入用户表数据

查询用户表数据

SQL语句翻译

查看查询历史记录

程序员常用的工具软件

该工具已收录到程序员常用的工具软件栏目中,欢迎关注该栏目发现更多优秀实用的开发工具!

一款.NET开源的i茅台自动预约(抢茅台)小助手

mikel阅读(339)

来源: 一款.NET开源的i茅台自动预约(抢茅台)小助手

今天大姚给大家分享一款.NET开源、基于WPF实现的i茅台APP接口自动化每日自动预约(抢茅台)小助手:HyggeImaotai。

图片

项目介绍

该项目通过接口自动化模拟i茅台APP实现每日自动预约茅台酒的功能,软件会在指定时间开始对管理的用户进行批量预约。

项目功能

  • 用户管理
  • 预约项目
  • 店铺管理
  • 日志管理

项目源代码

图片

工具下载

  • https://github.com/lisongkun/HyggeImaotai/releases
图片

源代码运行

图片
图片

功能截图

图片
图片
图片
图片
图片
图片

项目源码地址

更多项目实用功能和特性欢迎前往项目开源地址查看👀,别忘了给项目一个Star支持💖。

https://github.com/lisongkun/HyggeImaotai

优秀项目和框架精选

该项目已收录到C#/.NET/.NET Core优秀项目和框架精选中,关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践,提高开发工作效率和质量。坑已挖,欢迎大家踊跃提交PR推荐或自荐(让优秀的项目和框架不被埋没🤞)。

https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

无业游民写的最后一个.net有关项目框架 - 星仔007 - 博客园

mikel阅读(198)

来源: 无业游民写的最后一个.net有关项目框架 – 星仔007 – 博客园

理想很丰满,现实往往很残酷。

一种按照ddd的方式,根据业务来把自己需要的模块一个一个写出来,再按照模块把需要的接口一个一个的写出来,堆砌一些中间件,以及解耦的command,handler等等

,一个项目就这么成型了。上面的项目有一个非常清晰的特点,就是按需开发,不需要去可以定义业务相关的公共的模块,有就有没就没。这项目看起来没有什么公共框架,就是一个项目。当然这样效率性能也是最高的,不需要过多的包装一层又一层的公共代码。

有关示例如下,不做过多的赘述:

liuzhixin405/netcore-micro (github.com)

一种业务非常大,开发人员只需要写业务实现,这就需要一个公共框架,提供公共的可复制模块让业务人员写业务代码。

下面以为简洁的方式呈现这种开发模式,项目层级如下:

三个模块分别是业务模块,主机,基础模块。业务模块Business通过dll形式提供给host来完成注册和发布。

主机host可以存放公共的基础模块,例如注册、登录、认证等,这里省略。

业务模块存放业务代码,包括提供接口。

流程如下:request => 业务模块controller => business => service=> repository

整个项目接口不变,实现可各异。

在仓储层定义几个公共的方法,

复制代码
 public interface IRepository<TEntity,TID> where TEntity : IEntity<TID>
 {
     Task<ApiResult> AddAsync(TEntity entity);
     Task<ApiResult> UpdateAsync(TEntity entity);

     Task<ApiResult> DeleteAsync(Expression<Func<TEntity, bool>> filter);
     Task<ApiResult> DeleteAsync(TID id);
     // 通用分页查询
     Task<PagedResult<TEntity>> GetPagedAsync(PagingParameters<TEntity> pagingParameters);

     // 其他常用操作
     Task<IEnumerable<TEntity>> FindAsync(Expression<Func<TEntity, bool>> filter);

 }
复制代码

服务层也是同样的方法

复制代码
 [Intercept("business-service log")]
 public interface IService
 {
    Task<ApiResult> AddAsync(IRequestDto requestDto);
    Task<ApiResult> UpdateAsync(IRequestDto requestDto);
    Task<ApiResult> DeleteAsyncc(IRequestDto requestDto);
    Task<ApiResult> GetPagedAsyncc(IRequestDto requestDto) ;
    Task<ApiResult> FindAsyncc(IRequestDto requestDto);
 }
复制代码

 

依赖注入还是老一套,实现它就行。

复制代码
 public interface IModule
 {
     void ConfigureService(IServiceCollection services, IConfiguration configuration = null);
     void Configure(IApplicationBuilder app, IWebHostEnvironment env = null);
 }

 public abstract class ModuleBase : IModule
 {
     public virtual void ConfigureService(IServiceCollection services, IConfiguration configuration = null)
     {
     }

     public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment env = null)
     {
     }
 }
复制代码

在主机通过扫描assembly来注册服务

复制代码
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Project.Base.Reflect;
using System.Reflection;
using Project.Base.ProjExtension;
using Project.Base.Common;
using Project.Base.DependencyInjection;
using Project.Base.Module;
namespace Project.Host
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true);
            builder.Configuration.AddJsonFile("appsettings.Modules.json", optional: false, reloadOnChange: true);
            //IModule注入 ,然后扫描调用ConfigureService,Business注入需要的服务入口
            builder.Services.InitModule(builder.Configuration);
            var sp = builder.Services.BuildServiceProvider();
            var moduleInitializers = sp.GetServices<IModule>();
            foreach (var moduleInitializer in moduleInitializers)
            {
                moduleInitializer.ConfigureService(builder.Services, builder.Configuration);
            }
            // Add services to the container.
            var assemblys = GolbalConfiguration.Modules.Select(x => x.Assembly).ToList();


            var mvcBuilder=builder.Services.AddControllers().ConfigureApplicationPartManager(apm => {

                var folder = Path.Combine(Directory.GetCurrentDirectory(), "bus_lib");
                var serviceList = (builder.Configuration.GetSection("ServiceList").Get<string[]>()) ?? new string[] { "ADM" };//默认加载基础服务
                string[] serviceFiles = Directory.GetFiles(folder, "*.Api.dll").Where(x =>
                    serviceList.Any(y => x.Contains(y))
                ).ToArray();

                foreach (var file in serviceFiles)
                {
                    if (File.Exists(file))
                    {
                        var assembly = Assembly.LoadFrom(file);
                        var controllerAssemblyPart = new AssemblyPart(assembly);
                        apm.ApplicationParts.Add(controllerAssemblyPart);
                    }
                }
            });
            foreach (var assembly in assemblys)
            {
                // 扫描并注册其他程序集中的控制器
                mvcBuilder.AddApplicationPart(assembly);
                // 扫描并注册其他程序集中的服务   针对特性注入
                builder.Services.ReisterServiceFromAssembly(assembly);
            } 

            
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();
            builder.Services.AddBusinessServices();

            var app = builder.Build();
            ServiceLocator.Instance = app.Services;

            //imodule 的Configure调用,business可以实现中间件等操作
            foreach (var moduleInitializer in moduleInitializers)
            {
                moduleInitializer.Configure(app, app.Environment);
            }
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            app.UseHttpsRedirection();

            app.UseAuthorization();


            app.MapControllers();

            app.Run();
        }
    }
}
复制代码

 

业务需求注入代码如下:

复制代码
using ADM001_User.Model;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Bson.Serialization;
using MongoDB.Bson;
using MongoDB.Driver;
using Project.Base.IRepository;
using Project.Base.Module;
using Project.Base.Reflect;
using Project.Base.Repository;
using Project.Base.Services;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ADM001_User.Business.Settings;
using Project.Base.Model;

namespace ADM001_User.Business
{
    public class UserModule : ModuleBase
    {

        public override void ConfigureService(IServiceCollection services, IConfiguration configuration = null)
        {
            services.AddDbContext<UserDbContext>(options =>
       options.UseInMemoryDatabase("InMemoryDb"));

            services.AddScoped<IRepository<User, int>, GenericRepository<User, int, UserDbContext>>();
            services.AddTransient<IService, UserService>();

            AddMongo(services);
            AddMongoRepository<User, int>(services, "users");

        }


        private static IServiceCollection AddMongo(IServiceCollection services)
        {
            BsonSerializer.RegisterSerializer(new GuidSerializer(BsonType.String));
            BsonSerializer.RegisterSerializer(new DateTimeOffsetSerializer(BsonType.String));
            services.AddSingleton(serviceProvider =>
            {
                var configuration = serviceProvider.GetService<IConfiguration>();
                var serviceSettings = configuration.GetSection(nameof(ServiceSettings)).Get<ServiceSettings>();
                var mongoDbSettings = configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>();
                var mongoClient = new MongoClient(mongoDbSettings.ConenctionString);
                return mongoClient.GetDatabase(serviceSettings.ServiceName);
            });
            return services;
        }
        private static IServiceCollection AddMongoRepository<T, TID>(IServiceCollection services, string collectionName) where T : IEntity<TID>
        {
            services.AddSingleton<IRepository<User, int>>(serviceProvider =>
            {
                var db = serviceProvider.GetService<IMongoDatabase>();
                return new MongoRepository<User, int>(db, "collectionname");
            });
            return services;
        }
    }
}
复制代码

 

在business层加了aop,通过proxy的方式

复制代码
using Castle.DynamicProxy;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Project.Base.Reflect
{
    public static class ServiceExtension
    {
        private static readonly ProxyGenerator _generator = new ProxyGenerator();
        public static IServiceCollection AddBusinessServices(this IServiceCollection services)
        {
            var folder = Path.Combine(Directory.GetCurrentDirectory(), "bus_lib");

            var dllFiles = Directory.GetFiles(folder, "*.Business.dll");

            var assemblies = dllFiles.Select(Assembly.LoadFrom).ToArray();

            var businessTypes = assemblies.SelectMany(a => a.GetTypes().Where(t => t.IsClass&&!t.IsAbstract)).Where(type => type.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IBusiness<>))).ToList();
            CastleInterceptor castleInterceptor = new CastleInterceptor();

            foreach (var type in businessTypes)
            {
                var interfaceType = type.GetInterfaces().First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IBusiness<>));
                services.AddTransient(interfaceType, provider =>
                {
                    var target = ActivatorUtilities.CreateInstance(provider, type);
                    return _generator.CreateInterfaceProxyWithTarget(interfaceType, target, castleInterceptor);
                });
            }

            return services;
        }
    }
}
复制代码

在你需要的每个方法前加上特性就可以了

复制代码
using Project.Base.Model;
using Project.Base.ProjAttribute;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ADM001_User.Business
{
    /// <summary>
    /// 有需要就实现前后动作
    /// </summary>
    public class AddAop: BaseAopAttribute
    {
        public override Task After(BusinessAopContext aopContext)
        {
            return Task.CompletedTask;
        }

        public override Task Before(BusinessAopContext aopContext)
        {
            return Task.CompletedTask;
        }
    }
}
复制代码

 

再控制器层加了个公共的,不管是controller拦截还是公共的部分都可以写到这里

复制代码
 [Route("api/[controller]/[action]")]
 [ApiController]
 public class InitController<TModel>:ControllerBase
 {
     protected readonly ILogger<InitController<TModel>> _logger;
      public InitController(ILogger<InitController<TModel>> logger)
     {
         _logger = logger;

     }
   
 }
复制代码

 

该框架主打就是一个简陋,像日志,缓存 ,消息中间件都可以提前约定好公共接口,service层接口调用,business层注入需要的实现。按照接口和实现分离的方式该项目还需要调整下目录

地址如下:

liuzhixin405/single-arch (github.com)

C#/.NET/.NET Core优秀项目和框架2024年6月简报 - 追逐时光者 - 博客园

mikel阅读(205)

来源: C#/.NET/.NET Core优秀项目和框架2024年6月简报 – 追逐时光者 – 博客园

前言

公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项目和框架源码地址)。注意:排名不分先后,都是十分优秀的开源项目和框架,每周定期更新分享(欢迎关注公众号:追逐时光者,第一时间获取每周精选分享资讯🔔)。

简报GitHub开源地址:https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectMonthly.md

优秀项目和框架精选:https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

CsvHelper

ModernWpf

HyggeImaotai

WatchDog

Dorisoy.Pan

  • 项目简介: Dorisoy.Pan是一款基于.NET8开源(MIT License)、免费、跨平台文档管理系统,使用MS SQL 2012 / MySQL8.0(或更高版本)后端数据库,您可以在 Windows、Linux 或 Mac 上运行它,项目中的所有方法都是异步的,支持令牌基身份验证,项目体系结构遵循著名的软件模式和最佳安全实践。源代码是完全可定制的,热插拔且清晰的体系结构,使开发定制功能和遵循任何业务需求变得容易。
  • 项目源码地址: https://github.com/dorisoy/Dorisoy.Pan
  • 公众号详细介绍: https://mp.weixin.qq.com/s/_kAZdnJarAexDEA_d_Ldng

OxyPlot

Jvedio

  • 项目简介: Jvedio是.NET开源、功能强大的本地视频管理软件,支持扫描本地视频并导入软件,建立视频库,提取出视频的唯一识别码,自动分类视频,添加标签管理视频,使用人工智能识别演员,支持翻译信息,基于FFmpeg截取视频图片,Window桌面端流畅美观的应用软件。
  • 项目源码地址: https://github.com/hitchao/Jvedio
  • 公众号详细介绍: https://mp.weixin.qq.com/s/JwJFkZxrJVEqgXVxonT-1g

胡桃工具箱

  • 项目简介: 胡桃工具箱是一款.NET开源(MIT License)、免费、实用的多功能原神工具箱,专为现代化 Windows 平台设计,旨在改善桌面端玩家的游戏体验。通过将既有的官方资源与开发团队设计的全新功能相结合,它提供了一套完整且实用的工具集,且无需依赖任何移动设备。它不对游戏客户端进行任何破坏性修改以确保工具箱的安全性。
  • 项目源码地址: https://github.com/DGP-Studio/Snap.Hutao
  • 公众号详细介绍: https://mp.weixin.qq.com/s/5-Dybat5IagTk6XxaIHZug

TheAlgorithms/C-Sharp

  • 项目简介: 一个C#实现的各种算法集合,这些算法涵盖了计算机科学、数学和统计学、数据科学、机器学习、工程等多个领域。这些实现及其相关文档旨在为教育工作者和学生提供学习资源。因此,可能会找到针对同一目标使用不同算法策略和优化的多种实现。
  • 项目源码地址: https://github.com/TheAlgorithms/C-Sharp
  • 公众号详细介绍: https://mp.weixin.qq.com/s/KRl7Zoe3Co42zbWGJitRbg

FaceRecognitionDotNet

SeeSharpSnake

DotNetGuide技术社区交流群

  • DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目框架推荐、求职和招聘资讯、以及解决问题的平台。
  • 在DotNetGuide技术社区中,开发者们可以分享自己的技术文章、项目经验、学习心得、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
  • 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台。无论您是初学者还是有丰富经验的开发者,我们都希望能为您提供更多的价值和成长机会。

关于C#winform端Settings.settings的见解_winform settings-CSDN博客

mikel阅读(226)

来源: 关于C#winform端Settings.settings的见解_winform settings-CSDN博客

1.说明
由于最近工作比较忙很长时间没有写文章了,最近在项目中使用Settings.settings时遇见了一些问题,故作记录,希望各位大神指点。
2.Settings.settings说明
Settings.settings结构如上图,在Settings.settings中添加节点时Settings.Designer.cs自动生成该节点的属性,App.config自动生成节点信息。
3.使用方式介绍
private void button1_Click(object sender, EventArgs e)
{
    RefreshLabel();
}
private void RefreshLabel()
{
    label1.Text = “UserSave:” + Settings.Default.UserSave;
    label2.Text = “User:” + Settings.Default.User;
    label3.Text = “Application:” + Settings.Default.Application;
    Settings.Default.UserSave = “2”;
    Settings.Default.User = “2”;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    Settings.Default.Save();
}
4.属性介绍
名称:自定义节点名称,使用 Settings.Default.名称 获取或修改该节点的值
类型:设置节点的类型,获取或修改该节点的值必须使用相同的数据类型;
范围:包含用户和应用程序(后续单独说明);
值:可设置初始值;
5.属性-范围
范围包含了用户和应用程序
(1)用户节点
1.允许修改节点值;
2.修改节点的值仅在程序本次运行时生效,下次运行需要使用程序的默认值则不能调用
Settings.Default.Save();
3.修改节点的值需要在程序下次运行使用必须调用
Settings.Default.Save();
Settings.Default.Save(); 介绍
1.如果节点设置为用户,并且调用了Save()方法,会在C:\Users\Administrator\AppData\Local\项目名称\对应版本\1.0.0.0\user.config的文件中存储修改后的节点的值;
项目名称:当前运行的项目的名称
对应版本:共四种,包含:开发环境中启动的Debug、Release以及在Debug或Release中直接执行程序的.exe(可执行文件);
2.若未调用Save()方法,user.config不会生成或修改;
3.调用Save()方法时,仅保存调用前修改过所有节点的值,调用后修改的值不会改变,修改后节点在exe.config、vshost.exe.config不会显示修改后的值
4.建议在程序退出时,调用Save()方法;若仅需要节点在本次调用修改有效,则不能调用Save(),防止程序出现不可估计的错误;
5.若不仅包含了启动本次修改有效节点,还包含了修改后下次启动仍有效节点,建议在Settings.settings中添加用户节点,但是不能在程序调用Save方法,再配合使用Configuration使用。
(2)应用程序节点
1.节点的值不允许在程序中修改;
2.不会在C:\Users\Administrator\AppData\Local\项目名称\对应版本\1.0.0.0\user.config生成节点;
3.在app.config、exe.config、vshost.exe.config中生成节点
6.Configuration说明
在app.config添加节点,会在exe.config、vshost.exe.config中生成节点;
#region ConfigurationManager使用说明
// 想调用ConfigurationManager必须要先在工程里添加system.configuration程序集的引用
// 在引用点击右键选择添加引用,搜索Config就会找到
#endregion
using System;
using System.Configuration;
using System.Xml;
/******************************************************
* 模块作者: zheng
* 创建时间: 2021/6/27 20:18:15
* 功能描述: 1.用于对Winform端对EXE.config或操作vshost.exe.config文件的读写;
*           2.修改构造函数中初始化对象改变操作对象。
* 使用说明: 1.右击引用,添加System.Configuration;
*           2.使用该类时需要修改命名空间;
*           3.使用前建议向app.config添加节点,节点示例:
*           <appSettings file=””>
*             <add key=”光源连接端口” value=”com1″ />
*             <add key=”COM1″ value=”COM1,9600,8,None,1,已启用” />
*           </appSettings>
*******************************************************/
namespace MicroscaleMeasure.Utils
{
    class AppConfigUtil
    {
        /// <summary>
        /// 管理配置文件对象
        /// </summary>
        private static readonly Configuration MConfig;
        static AppConfigUtil()
        {
            //1.操作vshost.exe.config
            //MConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            //2.操作exe.config
            var file = System.Windows.Forms.Application.ExecutablePath;
            MConfig = ConfigurationManager.OpenExeConfiguration(file);
        }
        /// <summary>
        /// 获取AppSettings中某一节点值
        /// </summary>
        /// <param name=”key”>节点名称</param>
        public static string GetConfigValue(string key)
        {
            if (MConfig.AppSettings.Settings[key] != null)
                return MConfig.AppSettings.Settings[key].Value;
            else
                return string.Empty;
        }
        /// <summary>
        /// 修改配置文件,若节点不存在则添加节点
        /// </summary>
        /// <param name=”aKey”>需要修改的节点名称</param>
        /// <param name=”aValue”>需要修改的节点的值</param>
        public static void UpdateAppSettings(string aKey, string aValue)
        {
            if (MConfig.AppSettings.Settings[aKey] != null)
                MConfig.AppSettings.Settings[aKey].Value = aValue;// 修改
            else
            {
                var ass = (AppSettingsSection)MConfig.GetSection(“appSettings”);
                ass.Settings.Add(aKey, aValue);// 添加
            }
            MConfig.Save(ConfigurationSaveMode.Modified);// 保存修改
            ConfigurationManager.RefreshSection(“appSettings”);// 强制重新载入配置文件的连接配置
        }
    }
}
————————————————
                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_47492910/article/details/121810100