전술:
데이터베이스 작업의 캡슐화는 다음과 같습니다. 인터넷에서 사용 가능 이미 데이터베이스 작업을 매우 잘 지원하는 ORM 프레임워크 또는 .NET 자체 EF가 많이 있습니다. 이 기사는 데이터베이스 작업의 간단한 캡슐화에 대한 내 생각을 공유하기 위한 것입니다. 이 기사에서는 독자의 초점이 데이터베이스 작업 캡슐화를 분석하고 설계하는 방법이며 코드는 부차적이라고 생각합니다. 게다가 이 글은 내 첫 번째 글이다. 구현 방법을 알아내는 데 며칠이 걸렸다. 코드는 블로그가 게시될 때 작성되었다. 그래서 사용상 버그가 있을 수 있다고 생각하고, try catch 예외 디자인은 없습니다.
이 프레임워크는 데이터베이스 독립적이어야 하며 어떤 데이터베이스이든지 사용할 수 있습니다. 그러나 초점은 코드가 아닌 분석에 있습니다. 따라서 더 잘 설명하기 위해 SQL Server만 캡슐화했습니다. 다른 측면에서는 프레임워크가 체인 작성을 지원할 수 있지만 많은 프로그래밍 언어에서는 체인 작성에 큰 문제가 있을 것입니다. 낯설기 때문에 데이터베이스 접근도 체인 모드로 만들 수 있을 것 같아요. 이 프레임워크에서는 SQL 문 작성이 필요하지 않으며, 필요한 매개변수를 전달하고 해당 작업을 캡슐화하기만 하면 됩니다.
글을 읽기 전에 제네릭, 리플렉션, 링크에 대한 기본적인 지식을 갖고 있는 것이 가장 좋으며, 그렇지 않으면 읽기가 다소 어려울 수 있습니다.
요점:
구조 프레임은 상대적으로 간단하고 간단한 팩토리 패턴을 사용하므로 저자는 UML 다이어그램을 그려 설명하지 않고 텍스트를 사용하여 내부 메소드를 설명합니다.
팩토리 인터페이스를 설계할 때 인터페이스에는 체인 작성에 필요한 세 단계(부분이라고도 함)가 포함되어야 한다는 점을 고려해야 합니다. 기본 데이터베이스 작업(오픈) , 폐쇄, 생성 등), 데이터베이스 추가, 삭제, 수정, 데이터베이스에서 반환하는 데이터(여기서는 실행 단계라고 생각하는데, 왜 이전 단계가 아닌지 궁금하실 텐데요. 아래 참조) 및 필수적이지 않은 거래 작업.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Data.SqlClient; namespace Dal { public interface DbHelper { /// <summary> /// 创建数据库连接 /// </summary> /// <param name="connectionString">连接字符串</param> /// <returns></returns> DbHelper createConnection(string connectionString); /// <summary> /// 打开数据库 /// </summary> /// <returns></returns> DbHelper openConnection(); /// <summary> /// 关闭数据库 /// </summary> /// <returns></returns> DbHelper closeConnection(); /// <summary> /// 释放sqlConnection对象 /// </summary> void DisposedConnection(); /// <summary> /// 释放sqlCommand对象 /// </summary> void DisposedCommand(); /// <summary> /// 创建sqlCommand对象 /// </summary> /// <returns></returns> DbHelper createCommand(); /// <summary> /// 设置sqlCommand的类型 /// </summary> /// <param name="type">CommandType枚举类型</param> /// <returns></returns> DbHelper setCommandType(CommandType type); /// <summary> /// 要查询的表(多表以逗号隔开)、存储过程、视图名 /// </summary> /// <param name="Name"></param> /// <returns></returns> DbHelper FromName(string Name); /// <summary> /// 创建事务 /// </summary> /// <returns></returns> DbHelper beginTransaction(); /// <summary> /// 事务回滚 /// </summary> /// <returns></returns> DbHelper TransactionRowBack(); /// <summary> /// 事务提交 /// </summary> /// <returns></returns> DbHelper TransactionCommit(); /// <summary> /// 对多张表间的列进行联系 /// </summary> /// <param name="Fields">表间联系的字段</param> /// <returns></returns> DbHelper ForMulTable(string Fields); /// <summary> /// 查询 /// </summary> /// <param name="Fields">查询字段</param> /// <param name="Where">查询条件字典</param> /// <param name="otherWhere">其他条件</param> /// <returns></returns> DbHelper Select(string Fields = "*", Dictionary<string, object> Where = null, string otherWhere = ""); /// <summary> /// 更新 /// </summary> /// <param name="model">需要更新的对象</param> /// <param name="Where">更新条件</param> /// <param name="Fields">更新字段</param> /// <param name="otherWhere">其他条件</param> /// <returns></returns> DbHelper Update(object model, Dictionary<string, object> Where, string Fields = "", string otherWhere = ""); /// <summary> /// 插入 /// </summary> /// <param name="model">需要插入的对象</param> /// <param name="Fields">需要插入的字段</param> /// <returns></returns> DbHelper Insert(object model, string Fields = ""); /// <summary> /// 删除 /// </summary> /// <param name="Where">删除条件</param> /// <param name="otherWhere">其他条件</param> /// <returns></returns> DbHelper Delete(Dictionary<string, object> Where, string otherWhere = ""); /// <summary> /// 查询返回List /// </summary> /// <typeparam name="T">模型</typeparam> /// <returns></returns> List<T> ToList<T>() where T : class ,new(); /// <summary> /// 查询返回DataSet /// </summary> /// <param name="DatasetName"></param> /// <returns></returns> DataSet ToDataSet(string DatasetName); /// <summary> /// 查询返回DataTable /// </summary> /// <returns></returns> DataTable ToDataTable(); /// <summary> /// 执行存储过程 /// </summary> /// <param name="Parameter">存储过程参数</param> /// <returns></returns> DbHelper ExcuteProc(Dictionary<string, object> Parameter); /// <summary> /// 执行返回查询第一行第一列值 /// </summary> /// <returns></returns> object Result(); /// <summary> /// 返回执行的影响行数 /// </summary> /// <returns></returns> int ExcuteResult(); /// <summary> /// 用户自定义sqlCommand /// </summary> /// <param name="fun">委托</param> void UserDefineOperation(Action<dynamic> fun); } }
좋습니다. 코드를 읽은 후에도 여전히 구체적인 구현에 대해 모두가 혼란스러울 것입니다. 그런 다음 SQL Server를 사용하여 단계별로 구체적인 구현을 분석해 보겠습니다. 분석하다.
SQLHelper의 특정 구현 클래스에서는 설계에 꼭 필요한 필드이다. 설계 초기에는 각 데이터베이스가 사용하는 실행 객체 Command가 다르기 때문에 어떻게 하면 데이터베이스를 호환되게 만들 수 있을까 고민하다가 라이브러리를 더 잘 캡슐화하기 위해 sqlCommand는 외부에 노출되지 않도록 설계했지만, 내부적으로 사용됩니다. 노출된 메소드는 com의 속성 을 설정할 수 있으며, ExcuteName 객체는 실행 데이터를 저장합니다.
//连接字符串 string ConnectionString; //数据库连接对象 private SqlConnection conn; //执行对象 SqlCommand com; //表、存储过程、视图名称 string ExcuteName; //事务 SqlTransaction tran; //sql语句 StringBuilder sqlBuilderString; //参数 SqlParameter[] paras;
1부: 기본 데이터베이스 작업
createConnection 메소드: 이 메소드는 실제로 ConnectionString을 할당하는 새로운 sqlConnection은 일반적으로 사용되는 단일 케이스 모드를 채택하여 실행 중에 더욱 안전합니다. 그런데 이 싱글톤은 정적으로 설계한 것이 아니라 sqlConnection에 해당하는 Helper를 참조한 것인데, 일부 프로젝트에서는 여러 데이터베이스에 접근할 수 있을 것으로 생각되기 때문입니다. 그리고 생성할 때 한번 열었다 닫아 실제로 사용 가능한지 확인해보세요.
public DbHelper createConnection(string connectionString) { if (!ConnectionCanUse()) { this.ConnectionString = connectionString; conn = new SqlConnection(this.ConnectionString); } return this; } /// <summary> /// 检查conn是否能用 /// </summary> /// <returns></returns> public bool ConnectionCanUse() { if (conn == null) return false; try { conn.Open(); conn.Close(); }catch(Exception e) { return false; } return true; }
열기, 닫기, 연결 해제 및 명령 생성에 대한 설명은 한 문장만 있으므로 설명하지 않겠습니다.
기본 연산의 경우에도 sqlCommandType의 설정이 있는데, 저장 프로시저와 일반문 등의 연산 문자열이 확연히 다르기 때문에 메소드를 반드시 지정해야 한다. 설정하기 위해 작성되었습니다.
第二部分:增删改查的操作 这里就解释为什么sql语句不是在这个阶段执行。我觉得,如果将具体的执行放在这个阶段,那么就会导致方法重载过多,为什么?因为并不是所有人都能考虑到使用者要返回的类型,比如我想要List,或者DataSet等等,而且还会将这个方法的作用过重:在我设计的这些方法中,实操作的是对sql语句的生成,所以说为什么不能在这边执行,那么就不能重用。是吧,这样设计很灵活,将数据库真正执行放在下个阶段。而且这些方法都是链式的写法,所以会对执行能够很灵活的控制,最重要能够重用,不需要写别的重载方法,只需要一个方法。
生成sql语句在这也是简单的封装,如果要做起真的框架,我觉得sql字符串的组合还应该创建一个类,来更智能的组合用户的需求。
自然,里面使用到反射、Linq。不过笔者也一步步解释,将怎么设计分享给大家。
大家看到Select、Insert、Update、Delete的接口都有Where的条件字典。没错,反射就在这里使用。为了考虑到数据库的安全,所以sql自然只是简单的拼接,还应该使用参数。所以,反射就用在Where生成参数上。大家也许还看到别的otherWhere,这个怎么不设计成参数,因为Where能够实现的,其实就是赋值语句,也就是表内某字段 = 值,所以需要。在otherWhere中,存放的是其他特殊的条件。前面说这里设计的不完美,就因为如此,其实有些条件 like 或者 使用or ,虽然能够写在otherWhere中,但是没办法使用参数来控制。
那么接下来就是Fiels参数了,这个在各个方法充当不同的作用。Select是查询的字段,Update中是更新的字段,在Insert中是插入的字段,这样就灵活的控制了。在这些字段为空的时候,默认为全部,反射在这里就使用了,遍历模型对象中的属性,然后将它们一个个填进sql语句中。在这里比较注意的应该是插入,因为大家在写sql语句时候是这样的 insert tableName values(value,value....)这样的格式,这样是因为sql会自己对应值插入,而在程序中的模型类中,我想大家写属性可不是按顺序的吧,所以在反射遍历时候,就有可能将几个本来待在某个列位置的值去换了位置的情况。所以,这里在遍历的时候,应该按插入的完全格式来设计,也就是 insert tableName(Field,Field...) values(value,value...)。
在这几个方法中,Delete最简单。
public DbHelper Select(string Fields = "*",Dictionary<string,object> Where = null,string otherWhere = "") { sqlBuilderString = new StringBuilder(); sqlBuilderString.AppendLine("select " + Fields + " from " + this.ExcuteName); List<SqlParameter> paras = new List<SqlParameter>(); sqlBuilderString.AppendLine(" where 1 = 1 "); if (Where != null && Where.Count > 0) { paras = new List<SqlParameter>(); //遍历Where,将里面的条件添加到sqlParamter和sql语句中 Where.Keys.ToList().ForEach(o => { sqlBuilderString.AppendLine(" and "+ o + " = @" + o); paras.Add(new SqlParameter(o, Where[o])); }); } if(!string.IsNullOrEmpty(otherWhere)) { sqlBuilderString.AppendLine(otherWhere); } this.paras = paras.ToArray(); return this; }
public DbHelper Update(object model,Dictionary<string, object> Where,string Fields = "", string otherWhere = "") { Type t = model.GetType(); List<string> keys = Where.Keys.ToList(); sqlBuilderString = new StringBuilder(); bool firstnode = true; sqlBuilderString.AppendLine("update "+ExcuteName + " set "); List<SqlParameter> paras = new List<SqlParameter>(); if(string.IsNullOrEmpty(Fields)) { t.GetProperties().ToList().ForEach(o => { if (!firstnode) sqlBuilderString.Append(","); else firstnode = false; if(!keys.Contains(o.Name)) { sqlBuilderString.AppendLine(o.Name + " = @"+o.Name); paras.Add(new SqlParameter(o.Name,o.GetValue(model,null))); } }); }else { Fields.Split(',').ToList().ForEach(o => { sqlBuilderString.AppendLine(o + " = @" + o); paras.Add(new SqlParameter(o, t.GetProperty(o).GetValue(model, null))); }); } this.paras = paras.ToArray(); return this; }
public DbHelper Insert(object model,string Fields = "") { List<SqlParameter> paras = new List<SqlParameter>(); Type t = model.GetType(); sqlBuilderString = new StringBuilder(); sqlBuilderString.AppendLine("insert " + ExcuteName); if(string.IsNullOrEmpty(Fields)) { string s = ""; string s1=""; t.GetProperties().ToList().ForEach(o => { s += o.Name + ","; s1 += " @" + o.Name + ","; paras.Add(new SqlParameter(o.Name, o.GetValue(model, null))); }); s.Remove(s.LastIndexOf(','),1); s1.Remove(s.LastIndexOf(','), 1); sqlBuilderString.AppendLine("(" + s + ")"); sqlBuilderString.AppendLine(" values(" + s1 + ")"); }else { sqlBuilderString.AppendLine("(" + Fields + ")"); string s = ""; Fields.Split(',').ToList().ForEach(o => { s += " @" + o + ","; paras.Add(new SqlParameter(o, t.GetProperty(o).GetValue(model, null))); }); sqlBuilderString.AppendLine(" values(" + s + ")"); } this.paras = paras.ToArray(); return this; }
public DbHelper Delete(Dictionary<string,object> Where,string otherWhere = "") { sqlBuilderString = new StringBuilder(); List<SqlParameter> paras = new List<SqlParameter>(); sqlBuilderString.AppendLine("delete " + ExcuteName); sqlBuilderString.AppendLine(" where 1 = 1 "); Where.Keys.ToList().ForEach(o => { sqlBuilderString.AppendLine(" and " + o + " = @" + o); paras.Add(new SqlParameter(o, Where[o])); }); this.paras = paras.ToArray(); return this; }
最后一个阶段,那就是执行阶段,这里封装了些执行的方法。
这个也是简单,最重要的方法应该是setCommand,这个方法是对sqlCommand进行设置,执行的语句,以及添加参数。
private void setCommand() { if(com.CommandType== CommandType.StoredProcedure) { this.com.CommandText = ExcuteName; }else { this.com.CommandText = sqlBuilderString.ToString(); } this.paras.ToList().ForEach(o => { this.com.Parameters.Add(o); }); }
其他就是执行的语句。
public List<T> ToList<T>() where T:class ,new() { List<T> list = new List<T>(); setCommand(); SqlDataReader reader = com.ExecuteReader(); Type t = typeof(T); List<PropertyInfo> pros = t.GetProperties().ToList(); while(reader.Read()) { T model = new T(); pros.ForEach(o => { o.SetValue(model, reader[o.Name], null); }); list.Add(model); } reader.Dispose(); return list; } public DataSet ToDataSet(string DatasetName = "") { DataSet ds = new DataSet(); setCommand(); SqlDataAdapter adapter = new SqlDataAdapter(com); adapter.Fill(ds, string.IsNullOrEmpty(DatasetName) ? this.ExcuteName.Replace(",", "_") : DatasetName); adapter.Dispose(); return ds; } public DataTable ToDataTable() { DataTable dt = new DataTable(); setCommand(); SqlDataAdapter adapter = new SqlDataAdapter(com); adapter.Fill(dt); adapter.Dispose(); return dt; } public object Result() { setCommand(); return com.ExecuteScalar(); } public int ExcuteResult() { setCommand(); return com.ExecuteNonQuery(); } public DbHelper ExcuteProc(Dictionary<string,object> Parameter) { List<SqlParameter> paras = new List<SqlParameter>(); Parameter.Keys.ToList().ForEach(o => { paras.Add(new SqlParameter(o, Parameter[o])); }); return this; }
当然,还不能少了让用户自定义的方法,所以最后还留了个方法,参数是委托。委托里面的参数还是动态类型,这就懂了吧,想用户怎么用,你就怎么定义。
public void UserDefineOperation(Action<dynamic> fun) { fun(this.com); }
好了,设计也就到这里,下面就贴上SQLHelper完整的代码。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data;using System.Data.SqlClient;using System.Reflection;namespace Dal { public class SQLHelper:DbHelper { //连接字符串 string ConnectionString; //数据库连接对象 private SqlConnection conn; //执行对象 SqlCommand com; //表、存储过程、视图名称 string ExcuteName; //事务 SqlTransaction tran; //sql语句 StringBuilder sqlBuilderString; //参数 SqlParameter[] paras; private SQLHelper() { } ////// 创建sqlHelper静态方法 /// ///public static DbHelper getInstance() { return new SQLHelper(); } /// /// /// /// ///public DbHelper createConnection(string connectionString) { if (!ConnectionCanUse()) { this.ConnectionString = connectionString; conn = new SqlConnection(this.ConnectionString); } return this; } /// /// 检查conn是否能用 /// ///public bool ConnectionCanUse() { if (conn == null) return false; try { conn.Open(); conn.Close(); }catch(Exception e) { return false; } return true; } /// /// /// ///public DbHelper openConnection() { if(conn.State != ConnectionState.Open) this.conn.Open(); return this; } /// /// /// ///public DbHelper closeConnection() { if(conn.State != ConnectionState.Closed) this.conn.Close(); return this; } /// /// /// public void DisposedConnection() { if (!ConnectionBeUsed()) this.conn.Dispose(); } ////// 检查数据库是否在被打开使用 /// ///public bool ConnectionBeUsed() { if(conn.State == ConnectionState.Open) return true; return false; } /// /// /// ///public DbHelper createCommand() { if (this.com == null) { this.com = new SqlCommand(); com.Connection = this.conn; } return this; } /// /// /// public void DisposedCommand() { this.com.Dispose(); } ////// /// /// ///public DbHelper setCommandType(CommandType type) { this.com.CommandType = type; return this; } /// /// /// /// ///public DbHelper FromName(string Name) { this.ExcuteName = Name; return this; } /// /// /// ///public DbHelper beginTransaction() { this.tran = conn.BeginTransaction(); com.Transaction = this.tran; return this; } /// /// /// ///public DbHelper TransactionRowBack() { if(tran!=null) { tran.Rollback(); } return this; } /// /// /// ///public DbHelper TransactionCommit() { if(tran!=null) { tran.Commit(); tran = null; } return this; } /// /// /// /// /// /// ///public DbHelper Select(string Fields = "*",Dictionary<string,object> Where = null,string otherWhere = "") { sqlBuilderString = new StringBuilder(); sqlBuilderString.AppendLine("select " + Fields + " from " + this.ExcuteName); List<SqlParameter> paras = new List<SqlParameter>(); sqlBuilderString.AppendLine(" where 1 = 1 "); if (Where != null && Where.Count > 0) { paras = new List<SqlParameter>(); //遍历Where,将里面的条件添加到sqlParamter和sql语句中 Where.Keys.ToList().ForEach(o => { sqlBuilderString.AppendLine(" and "+ o + " = @" + o); paras.Add(new SqlParameter(o, Where[o])); }); } if(!string.IsNullOrEmpty(otherWhere)) { sqlBuilderString.AppendLine(otherWhere); } this.paras = paras.ToArray(); return this; } public DbHelper ForMulTable(string Fields) { List tables = ExcuteName.Split(',').ToList(); Fields.Split(',').ToList().ForEach(o => { for(int i = 0;i 最后还有两个事务的方法,前面忘记说了,其实就是SqlTransaction,在里面的sqlCommand加上这个,就可以实现。或许有人会问,如果有同一时间段有好几个sqlCommand怎么办?不会的,sqlCommand我也设置成单例,就不会发生控制不了的事情了。
결론: 제가 처음으로 '어리석은 일'을 많이 해봤지만, 그래도 대학생 후배라서 부담스럽게 글을 쓰게 된다면 걱정이 됩니다. 조롱의 대상이 될 뿐이고, 유치한 '일'이 모두가 볼 수 있도록 온라인에 게시하기에는 너무 부끄럽습니다. 그래서 며칠 동안 고민한 끝에 꽤 유용하다고 생각되는 패키지를 작성했습니다. 비록 많은 프로젝트에서는 작동하지 않을 수도 있지만 독자들이 스스로 더 깊이 생각할 수 있을 것입니다.
이 프레임워크는 SQL 문 조합, 호출 시 예외 처리, 체인 조합을 더 잘 구현하는 방법 등을 더 잘 캡슐화해야 한다고 생각합니다. , 다중 데이터베이스 처리 제어, 잠금 추가 등도 가능하다고 생각합니다. 웹을 할 때 winform과 같지 않고 각 끝마다 자체 연결이 있습니다. 제가 생각하는 또 다른 좋은 점은 프레임워크가 기본 키와 외래 키를 식별하고 프로그램에서 SQL로 연결을 설정할 수 있도록 모델에 대한 처리를 수행하고 기능을 추가하는 것입니다. 그러면 독자들이 생각할 몫이다.
위 내용은 C# .NET의 더욱 스마트한 데이터베이스 작업 캡슐화에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

C#.NETISVERSATILEFORBOTHWEBBANDDESKTOPDEVENTROMMENT.1) FORWEB, useASP.NETFORRICHINTERFACES.3) FORDESKTOP.3) USEXAMARINFORCROSS-PLATFORMDEEVENTRIMMENT, LINABILEDEV, MACODEDEV, and MACODEDOWS, 및 MACODEDOWS.

C# 및 .NET는 지속적인 업데이트 및 최적화를 통해 신흥 기술의 요구에 적응합니다. 1) C# 9.0 및 .NET5는 레코드 유형 및 성능 최적화를 소개합니다. 2) .NETCORE는 클라우드 네이티브 및 컨테이너화 된 지원을 향상시킵니다. 3) ASP.NETCORE는 최신 웹 기술과 통합됩니다. 4) ML.NET는 기계 학습 및 인공 지능을 지원합니다. 5) 비동기 프로그래밍 및 모범 사례는 성능을 향상시킵니다.

C#.netissuitable forenterprise-levelapplications는 richlibraries, androbustperformance, 그러나 itmaynotbeidealforcross-platformdevelopmentorwhenrawspeediscritical, wherelanguagesslikerustorthightordogrordogrognegrognegrognegrognecross-platformdevelopmentor.

.NET에서 C#의 프로그래밍 프로세스에는 다음 단계가 포함됩니다. 1) C# 코드 작성, 2) 중간 언어 (IL)로 컴파일하고 .NET 런타임 (CLR)에 의해 실행됩니다. .NET에서 C#의 장점은 현대적인 구문, 강력한 유형 시스템 및 .NET 프레임 워크와의 긴밀한 통합으로 데스크탑 응용 프로그램에서 웹 서비스에 이르기까지 다양한 개발 시나리오에 적합합니다.

C#은 Microsoft가 개발 한 최신 객체 지향 프로그래밍 언어이며 .NET 프레임 워크의 일부로 개발되었습니다. 1.C#은 캡슐화, 상속 및 다형성을 포함한 객체 지향 프로그래밍 (OOP)을 지원합니다. 2. C#의 비동기 프로그래밍은 응용 프로그램 응답 성을 향상시키기 위해 비동기 및 키워드를 기다리는 키워드를 통해 구현됩니다. 3. LINQ를 사용하여 데이터 컬렉션을 간결하게 처리하십시오. 4. 일반적인 오류에는 NULL 참조 예외 및 인덱스 외 예외가 포함됩니다. 디버깅 기술에는 디버거 사용 및 예외 처리가 포함됩니다. 5. 성능 최적화에는 StringBuilder 사용 및 불필요한 포장 및 Unboxing을 피하는 것이 포함됩니다.

C#.NET 애플리케이션에 대한 테스트 전략에는 단위 테스트, 통합 테스트 및 엔드 투 엔드 테스트가 포함됩니다. 1. 단위 테스트를 통해 MSTEST, NUNIT 또는 XUNIT 프레임 워크를 사용하여 코드의 최소 단위가 독립적으로 작동합니다. 2. 통합 테스트는 일반적으로 사용되는 시뮬레이션 된 데이터 및 외부 서비스를 결합한 여러 장치의 기능을 확인합니다. 3. 엔드 투 엔드 테스트는 사용자의 완전한 작동 프로세스를 시뮬레이션하며 셀레늄은 일반적으로 자동 테스트에 사용됩니다.

C# 수석 개발자와의 인터뷰에는 비동기 프로그래밍, LINQ 및 .NET 프레임 워크의 내부 작업 원리와 같은 핵심 지식을 마스터하는 것이 필요합니다. 1. 비동기 프로그래밍은 비동기를 통해 작업을 단순화하고 응용 프로그램 응답 성을 향상시키기 위해 기다리고 있습니다. 2.linq는 SQL 스타일로 데이터를 운영하고 성능에주의를 기울입니다. 3. Net Framework의 CLR은 메모리를 관리하며 가비지 컬렉션은주의해서 사용해야합니다.

C#.NET 인터뷰 질문 및 답변에는 기본 지식, 핵심 개념 및 고급 사용이 포함됩니다. 1) 기본 지식 : C#은 Microsoft가 개발 한 객체 지향 언어이며 주로 .NET 프레임 워크에 사용됩니다. 2) 핵심 개념 : 위임 및 이벤트는 동적 바인딩 방법을 허용하고 LINQ는 강력한 쿼리 기능을 제공합니다. 3) 고급 사용 : 비동기 프로그래밍은 응답 성을 향상시키고 표현 트리는 동적 코드 구성에 사용됩니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

Dreamweaver Mac版
시각적 웹 개발 도구

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.
