ทำการแทรกและอัพเดตด้วย Dapper


195

ฉันสนใจที่จะใช้ Dapper - แต่จากสิ่งที่ฉันสามารถบอกได้ก็รองรับ Query และ Execute เท่านั้น ฉันไม่เห็นว่า Dapper มีวิธีการใส่และอัปเดตวัตถุ

ระบุว่าโครงการของเรา (โครงการส่วนใหญ่?) จำเป็นต้องทำการแทรกและอัปเดตแนวปฏิบัติที่ดีที่สุดสำหรับการแทรกและอัปเดตควบคู่ไปกับผู้ทำแผนที่คืออะไร

โดยเฉพาะอย่างยิ่งเราจะไม่ต้องหันไปใช้วิธีการสร้างพารามิเตอร์ของ ADO.NET เป็นต้น

คำตอบที่ดีที่สุดที่ฉันสามารถหาได้ในตอนนี้คือใช้ LinqToSQL สำหรับแทรกและอัพเดต มีคำตอบที่ดีกว่านี้ไหม?


3
มีส่วนขยาย Contrib นี้จาก Dapper.NET เองที่ฉันใช้ github.com/StackExchange/dapper-dot-net/tree/master/…
Rajiv

คำตอบ:


201

เรากำลังมองหาผู้สร้างไม่กี่คนที่ยังคงตัดสินใจเกี่ยวกับ API และถ้ามันเป็นหลักหรือไม่ ดู: https://code.google.com/archive/p/dapper-dot-net/issues/6สำหรับความคืบหน้า

ในระหว่างนี้คุณสามารถทำสิ่งต่อไปนี้

val = "my value";
cnn.Execute("insert into Table(val) values (@val)", new {val});

cnn.Execute("update Table set val = @val where Id = @id", new {val, id = 1});

เป็นต้น

ดูโพสต์บล็อกของฉันด้วย: ปัญหา INSERT ที่น่ารำคาญ

ปรับปรุง

ดังที่ได้กล่าวไว้ในความคิดเห็นขณะนี้มีส่วนขยายหลายรายการในโครงการDapper.ContribในรูปแบบของIDbConnectionวิธีการส่วนขยายเหล่านี้:

T Get<T>(id);
IEnumerable<T> GetAll<T>();
int Insert<T>(T obj);
int Insert<T>(Enumerable<T> list);
bool Update<T>(T obj);
bool Update<T>(Enumerable<T> list);
bool Delete<T>(T obj);
bool Delete<T>(Enumerable<T> list);
bool DeleteAll<T>();

4
สวัสดีแซมพบคำตอบ SO ของคุณด้วย google และฉันสงสัยว่าบรรทัดสุดท้ายของรหัสควรมีคำsetว่าcnn.Execute("update Table SET val = @val where Id = @id", new {val, id = 1});dapper นี้หรือไม่? ฉันยังใหม่กับนักทำแผนที่และกำลังมองหาตัวอย่างการอัปเดต :)
JP Hellemons

1
@JPHellemons ฉันลองvar updateCat = connection.Execute("UPDATE tCategories SET sCategory = @val WHERE iCategoryID = @id", new { val = "dapper test", id = 23 });และใช้งานได้ หากไม่ใช้ SET ฉันจะได้รับข้อผิดพลาดทางไวยากรณ์ของ SQLException ใกล้กับ sCategory
แพ่งราคา

3
กรอไปข้างหน้าถึงธันวาคม 2015: github.com/StackExchange/dapper-dot-net/tree/master/…
Rosdi Kasim

3
@RosdiKasim สิ่งนี้ไม่ได้เป็นการทำลายวัตถุประสงค์ของการใช้ Dapper หรือไม่? ฉันต้องการใช้ SQL นามธรรมนี้มัน ฉันพลาดอะไรไป
johnny

2
@ Johnny มันเป็นแค่คลาสผู้ช่วย ... บางคนต้องการรหัสของพวกเขาสั้นที่สุดเท่าที่จะเป็นไปได้ ... คุณไม่จำเป็นต้องใช้มันถ้าคุณไม่ต้องการมัน
Rosdi Kasim

68

การดำเนินการ CRUD โดยใช้ Dapper เป็นเรื่องง่าย ฉันได้กล่าวถึงตัวอย่างด้านล่างที่จะช่วยคุณในการดำเนินงาน CRUD

รหัสสำหรับC RUD:

วิธีที่ # 1:วิธีนี้จะใช้เมื่อคุณกำลังแทรกค่าจากเอนทิตีที่แตกต่างกัน

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string insertQuery = @"INSERT INTO [dbo].[Customer]([FirstName], [LastName], [State], [City], [IsActive], [CreatedOn]) VALUES (@FirstName, @LastName, @State, @City, @IsActive, @CreatedOn)";

    var result = db.Execute(insertQuery, new
    {
        customerModel.FirstName,
        customerModel.LastName,
        StateModel.State,
        CityModel.City,
        isActive,
        CreatedOn = DateTime.Now
    });
}

วิธีที่ # 2:วิธีนี้ใช้เมื่อคุณสมบัติเอนทิตีของคุณมีชื่อเดียวกันกับคอลัมน์ SQL ดังนั้น Dapper ที่เป็น ORM จะจับคู่คุณสมบัติเอนทิตีกับคอลัมน์ SQL ที่ตรงกัน

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string insertQuery = @"INSERT INTO [dbo].[Customer]([FirstName], [LastName], [State], [City], [IsActive], [CreatedOn]) VALUES (@FirstName, @LastName, @State, @City, @IsActive, @CreatedOn)";

    var result = db.Execute(insertQuery, customerViewModel);
}

รหัสสำหรับ C R UD:

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string selectQuery = @"SELECT * FROM [dbo].[Customer] WHERE FirstName = @FirstName";

    var result = db.Query(selectQuery, new
    {
        customerModel.FirstName
    });
}

รหัสสำหรับ CR U D:

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string updateQuery = @"UPDATE [dbo].[Customer] SET IsActive = @IsActive WHERE FirstName = @FirstName AND LastName = @LastName";

    var result = db.Execute(updateQuery, new
    {
        isActive,
        customerModel.FirstName,
        customerModel.LastName
    });
}

รหัสสำหรับ CRU D :

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string deleteQuery = @"DELETE FROM [dbo].[Customer] WHERE FirstName = @FirstName AND LastName = @LastName";

    var result = db.Execute(deleteQuery, new
    {
        customerModel.FirstName,
        customerModel.LastName
    });
}

26

คุณสามารถทำได้ด้วยวิธีดังกล่าว:

sqlConnection.Open();

string sqlQuery = "INSERT INTO [dbo].[Customer]([FirstName],[LastName],[Address],[City]) VALUES (@FirstName,@LastName,@Address,@City)";
sqlConnection.Execute(sqlQuery,
    new
    {
        customerEntity.FirstName,
        customerEntity.LastName,
        customerEntity.Address,
        customerEntity.City
    });

sqlConnection.Close();

36
คุณควรใช้using-statementเพื่อให้การเชื่อมต่อถูกปิดแม้ในกรณีที่มีข้อยกเว้น
Tim Schmelter

12
คุณก็สามารถผ่าน customerEntity โดยตรงแทนการใช้ชนิดที่ไม่ระบุชื่อ ...
โทมัส Levesque

@ThomasLevesque คุณหมายถึงอะไร คุณสามารถให้ตัวอย่างรหัสเล็ก ๆ ของสิ่งที่คุณหมายถึงอะไร
iaacp

4
@iaacp ฉันหมายถึง:sqlConnection.Execute(sqlQuery, customerEntity);
Thomas Levesque

1
@ThomasLevesque เราสามารถอัปเดตโดยใช้รูปแบบเดียวกันได้หรือไม่ เช่นsqlConnection.Execute(sqlQuery, customerEntity);
Shankar

16

ใช้Dapper.Contribมันง่ายเหมือนนี้

แทรกรายการ:

public int Insert(IEnumerable<YourClass> yourClass)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    {
        conn.Open();
        return conn.Insert(yourClass) ;
    }
}

แทรกเดี่ยว:

public int Insert(YourClass yourClass)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    {
        conn.Open();
        return conn.Insert(yourClass) ;
    }
}

อัปเดตรายการ:

public bool Update(IEnumerable<YourClass> yourClass)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    {
        conn.Open();
        return conn.Update(yourClass) ;
    }
}

อัปเดตเดียว:

public bool Update(YourClass yourClass)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    {
        conn.Open();
        return conn.Update(yourClass) ;
    }
}

ที่มา: https://github.com/StackExchange/Dapper/tree/master/Dapper.Contrib


1
การใช้ด้านบนเพื่อแทรกวัตถุเดียวคุณสามารถดึงหมายเลขประจำตัวใหม่ออกมาและนำกลับมาใช้ในแบบจำลองของคุณ ... แต่คุณจะทำอย่างไรเพื่อแทรกรายการวัตถุ - วัตถุในรายการไม่มี เขตข้อมูลประจำตัว คุณต้องวนซ้ำในรายการแล้วใส่ทีละครั้งเพื่อนำ ID ใหม่ออกมาในแต่ละครั้งหรือไม่?
Harag

1
@harag หากคุณต้องการ ID ใหม่ที่อื่นฉันคิดว่าคุณต้องทำอย่างนั้น Entity Framework จัดการชนิดอ้างอิงเช่นคลาสโดยไม่มีปัญหากับส่วนแทรก แต่ฉันไม่รู้ว่า Dapper.Contrib ทำงานอย่างไรถ้านั่นคือมุมของคุณ
Ogglas

5
@Ogglas ขอบคุณ ฉันสังเกตเห็น "การเชื่อมต่อ. แทรก (myObject)" จะอัปเดตคุณสมบัติ "[คีย์]" ของ "myObject" ถ้าฉันเพียงแค่แทรกวัตถุหนึ่ง แต่ถ้าฉันใส่วัตถุ 5 รายการโดยใช้สิ่งเดียวกัน "connection.Insert (myObjectList)" จากนั้นไม่มีคุณสมบัติ [keys] ที่อัปเดตดังนั้นฉันต้องทำรายการ foreach ในรายการด้วยตนเองและใส่ทีละรายการ
Harag

1
ในconn.Update(yourClass)ถ้าคุณสมบัติบางอย่างเป็นโมฆะแล้วปรับปรุงเขตข้อมูลที่จะเป็นโมฆะ ? ไม่ทำงาน. การปรับปรุงข้อมูลให้เป็น NULL Not partials updates
Kiquenet

5

นอกจากนี้คุณยังสามารถใช้ Dapper กับขั้นตอนการจัดเก็บและวิธีการทั่วไปซึ่งทุกอย่างสามารถจัดการได้ง่าย

กำหนดการเชื่อมต่อของคุณ:

public class Connection: IDisposable
{
    private static SqlConnectionStringBuilder ConnectionString(string dbName)
    {
        return new SqlConnectionStringBuilder
            {
                ApplicationName = "Apllication Name",
                DataSource = @"Your source",
                IntegratedSecurity = false,
                InitialCatalog = Database Name,
                Password = "Your Password",
                PersistSecurityInfo = false,
                UserID = "User Id",
                Pooling = true
            };
    }

    protected static IDbConnection LiveConnection(string dbName)
    {
        var connection = OpenConnection(ConnectionString(dbName));
        connection.Open();
        return connection;
    }

    private static IDbConnection OpenConnection(DbConnectionStringBuilder connectionString)
    {
        return new SqlConnection(connectionString.ConnectionString);
    }

    protected static bool CloseConnection(IDbConnection connection)
    {
        if (connection.State != ConnectionState.Closed)
        {
            connection.Close();
            // connection.Dispose();
        }
        return true;
    }

    private static void ClearPool()
    {
        SqlConnection.ClearAllPools();
    }

    public void Dispose()
    {
        ClearPool();
    }
}

สร้างอินเตอร์เฟสเพื่อกำหนดวิธี Dapper ที่คุณต้องการ:

 public interface IDatabaseHub
    {
   long Execute<TModel>(string storedProcedureName, TModel model, string dbName);

        /// <summary>
        /// This method is used to execute the stored procedures with parameter.This is the generic version of the method.
        /// </summary>
        /// <param name="storedProcedureName">This is the type of POCO class that will be returned. For more info, refer to https://msdn.microsoft.com/en-us/library/vstudio/dd456872(v=vs.100).aspx. </param>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="model">The model object containing all the values that passes as Stored Procedure's parameter.</param>
        /// <returns>Returns how many rows have been affected.</returns>
        Task<long> ExecuteAsync<TModel>(string storedProcedureName, TModel model, string dbName);

        /// <summary>
        /// This method is used to execute the stored procedures with parameter. This is the generic version of the method.
        /// </summary>
        /// <param name="storedProcedureName">Stored Procedure's name. Expected to be a Verbatim String, e.g. @"[Schema].[Stored-Procedure-Name]"</param>
        /// <param name="parameters">Parameter required for executing Stored Procedure.</param>        
        /// <returns>Returns how many rows have been affected.</returns>         
        long Execute(string storedProcedureName, DynamicParameters parameters, string dbName);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="storedProcedureName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        Task<long> ExecuteAsync(string storedProcedureName, DynamicParameters parameters, string dbName);
}

ใช้อินเทอร์เฟซ:

     public class DatabaseHub : Connection, IDatabaseHub
        {

 /// <summary>
        /// This function is used for validating if the Stored Procedure's name is correct.
        /// </summary>
        /// <param name="storedProcedureName">Stored Procedure's name. Expected to be a Verbatim String, e.g. @"[Schema].[Stored-Procedure-Name]"</param>
        /// <returns>Returns true if name is not empty and matches naming patter, otherwise returns false.</returns>

        private static bool IsStoredProcedureNameCorrect(string storedProcedureName)
        {
            if (string.IsNullOrEmpty(storedProcedureName))
            {
                return false;
            }

            if (storedProcedureName.StartsWith("[") && storedProcedureName.EndsWith("]"))
            {
                return Regex.IsMatch(storedProcedureName,
                    @"^[\[]{1}[A-Za-z0-9_]+[\]]{1}[\.]{1}[\[]{1}[A-Za-z0-9_]+[\]]{1}$");
            }
            return Regex.IsMatch(storedProcedureName, @"^[A-Za-z0-9]+[\.]{1}[A-Za-z0-9]+$");
        }

     /// <summary>
            /// This method is used to execute the stored procedures without parameter.
            /// </summary>
            /// <param name="storedProcedureName">Stored Procedure's name. Expected to be a Verbatim String, e.g. @"[Schema].[Stored-Procedure-Name]"</param>
            /// <param name="model">The model object containing all the values that passes as Stored Procedure's parameter.</param>
            /// <typeparam name="TModel">This is the type of POCO class that will be returned. For more info, refer to https://msdn.microsoft.com/en-us/library/vstudio/dd456872(v=vs.100).aspx. </typeparam>
            /// <returns>Returns how many rows have been affected.</returns>

            public long Execute<TModel>(string storedProcedureName, TModel model, string dbName)
            {
                if (!IsStoredProcedureNameCorrect(storedProcedureName))
                {
                    return 0;
                }

                using (var connection = LiveConnection(dbName))
                {
                    try
                    {
                        return connection.Execute(
                            sql: storedProcedureName,
                            param: model,
                            commandTimeout: null,
                            commandType: CommandType.StoredProcedure
                            );

                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        CloseConnection(connection);
                    }
                }
            }

            public async Task<long> ExecuteAsync<TModel>(string storedProcedureName, TModel model, string dbName)
            {
                if (!IsStoredProcedureNameCorrect(storedProcedureName))
                {
                    return 0;
                }

                using (var connection = LiveConnection(dbName))
                {
                    try
                    {
                        return await connection.ExecuteAsync(
                            sql: storedProcedureName,
                            param: model,
                            commandTimeout: null,
                            commandType: CommandType.StoredProcedure
                            );

                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        CloseConnection(connection);
                    }
                }
            }

            /// <summary>
            /// This method is used to execute the stored procedures with parameter. This is the generic version of the method.
            /// </summary>
            /// <param name="storedProcedureName">Stored Procedure's name. Expected to be a Verbatim String, e.g. @"[Schema].[Stored-Procedure-Name]"</param>
            /// <param name="parameters">Parameter required for executing Stored Procedure.</param>        
            /// <returns>Returns how many rows have been affected.</returns>

            public long Execute(string storedProcedureName, DynamicParameters parameters, string dbName)
            {
                if (!IsStoredProcedureNameCorrect(storedProcedureName))
                {
                    return 0;
                }

                using (var connection = LiveConnection(dbName))
                {
                    try
                    {
                        return connection.Execute(
                            sql: storedProcedureName,
                            param: parameters,
                            commandTimeout: null,
                            commandType: CommandType.StoredProcedure
                            );
                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        CloseConnection(connection);
                    }
                }
            }



            public async Task<long> ExecuteAsync(string storedProcedureName, DynamicParameters parameters, string dbName)
            {
                if (!IsStoredProcedureNameCorrect(storedProcedureName))
                {
                    return 0;
                }

                using (var connection = LiveConnection(dbName))
                {
                    try
                    {
                        return await connection.ExecuteAsync(
                            sql: storedProcedureName,
                            param: parameters,
                            commandTimeout: null,
                            commandType: CommandType.StoredProcedure
                            );

                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        CloseConnection(connection);
                    }
                }
            }

    }

ตอนนี้คุณสามารถโทรจากแบบจำลองตามความต้องการของคุณ:

public class DeviceDriverModel : Base
    {
 public class DeviceDriverSaveUpdate
        {
            public string DeviceVehicleId { get; set; }
            public string DeviceId { get; set; }
            public string DriverId { get; set; }
            public string PhoneNo { get; set; }
            public bool IsActive { get; set; }
            public string UserId { get; set; }
            public string HostIP { get; set; }
        }


        public Task<long> DeviceDriver_SaveUpdate(DeviceDriverSaveUpdate obj)
        {

            return DatabaseHub.ExecuteAsync(
                    storedProcedureName: "[dbo].[sp_SaveUpdate_DeviceDriver]", model: obj, dbName: AMSDB);//Database name defined in Base Class.
        }
}

คุณสามารถส่งผ่านพารามิเตอร์ได้เช่นกัน:

public Task<long> DeleteFuelPriceEntryByID(string FuelPriceId, string UserId)
        {


            var parameters = new DynamicParameters();
            parameters.Add(name: "@FuelPriceId", value: FuelPriceId, dbType: DbType.Int32, direction: ParameterDirection.Input);
            parameters.Add(name: "@UserId", value: UserId, dbType: DbType.String, direction: ParameterDirection.Input);

            return DatabaseHub.ExecuteAsync(
                    storedProcedureName: @"[dbo].[sp_Delete_FuelPriceEntryByID]", parameters: parameters, dbName: AMSDB);

        }

ตอนนี้โทรจากตัวควบคุมของคุณ:

var queryData = new DeviceDriverModel().DeviceInfo_Save(obj);

หวังว่ามันจะป้องกันการทำซ้ำรหัสของคุณและให้ความปลอดภัย;



0

แทนที่จะใช้ห้องสมุดบุคคลที่สามสำหรับการดำเนินการค้นหาฉันขอแนะนำให้คุณเขียนแบบสอบถามด้วยตัวเอง เพราะการใช้แพ็คเกจของบุคคลที่สามอื่น ๆ จะได้ประโยชน์จากการใช้ dapper นั่นคือความยืดหยุ่นในการเขียนแบบสอบถาม

ขณะนี้มีปัญหาเกี่ยวกับการเขียนแทรกหรือปรับปรุงแบบสอบถามสำหรับวัตถุทั้งหมด สำหรับสิ่งนี้เราสามารถสร้างผู้ช่วยเหลือได้ดังต่อไปนี้:

InsertQueryBuilder:

 public static string InsertQueryBuilder(IEnumerable < string > fields) {


  StringBuilder columns = new StringBuilder();
  StringBuilder values = new StringBuilder();


  foreach(string columnName in fields) {
   columns.Append($ "{columnName}, ");
   values.Append($ "@{columnName}, ");

  }
  string insertQuery = $ "({ columns.ToString().TrimEnd(',', ' ')}) VALUES ({ values.ToString().TrimEnd(',', ' ')}) ";

  return insertQuery;
 }

ตอนนี้เพียงแค่ส่งชื่อคอลัมน์เพื่อแทรกการสืบค้นทั้งหมดจะถูกสร้างขึ้นโดยอัตโนมัติดังนี้:

List < string > columns = new List < string > {
 "UserName",
 "City"
}
//QueryBuilder is the class having the InsertQueryBuilder()
string insertQueryValues = QueryBuilderUtil.InsertQueryBuilder(columns);

string insertQuery = $ "INSERT INTO UserDetails {insertQueryValues} RETURNING UserId";

Guid insertedId = await _connection.ExecuteScalarAsync < Guid > (insertQuery, userObj);

คุณยังสามารถปรับเปลี่ยนฟังก์ชั่นเพื่อส่งกลับคำสั่ง INSERT ทั้งหมดโดยส่งพารามิเตอร์ TableName

ตรวจสอบให้แน่ใจว่าชื่อคุณสมบัติคลาสตรงกับชื่อเขตข้อมูลในฐานข้อมูล จากนั้นมีเพียงคุณเท่านั้นที่สามารถผ่าน obj ทั้งหมด (เช่น userObj ในกรณีของเรา) และค่าจะถูกแมปโดยอัตโนมัติ

ในทำนองเดียวกันคุณสามารถมีฟังก์ชั่นตัวช่วยสำหรับแบบสอบถาม UPDATE ได้เช่นกัน:

  public static string UpdateQueryBuilder(List < string > fields) {
   StringBuilder updateQueryBuilder = new StringBuilder();

   foreach(string columnName in fields) {
    updateQueryBuilder.AppendFormat("{0}=@{0}, ", columnName);
   }
   return updateQueryBuilder.ToString().TrimEnd(',', ' ');
  }

และใช้มันเช่น:

List < string > columns = new List < string > {
 "UserName",
 "City"
}
//QueryBuilder is the class having the UpdateQueryBuilder()
string updateQueryValues = QueryBuilderUtil.UpdateQueryBuilder(columns);

string updateQuery =  $"UPDATE UserDetails SET {updateQueryValues} WHERE UserId=@UserId";

await _connection.ExecuteAsync(updateQuery, userObj);

แม้ว่าในฟังก์ชันผู้ช่วยเหล่านี้คุณต้องผ่านชื่อของเขตข้อมูลที่คุณต้องการแทรกหรืออัปเดต แต่อย่างน้อยคุณก็สามารถควบคุมการสืบค้นได้อย่างเต็มที่และยังสามารถรวมคำสั่ง WHERE ที่แตกต่างกันตามที่ต้องการ

ผ่านฟังก์ชั่นตัวช่วยนี้คุณจะบันทึกบรรทัดของรหัสต่อไปนี้:

สำหรับการแทรกแบบสอบถาม:

 $ "INSERT INTO UserDetails (UserName,City) VALUES (@UserName,@City) RETURNING UserId";

สำหรับ Query Update:

$"UPDATE UserDetails SET UserName=@UserName, City=@City WHERE UserId=@UserId";

ดูเหมือนว่าจะมีความแตกต่างของโค้ดไม่กี่บรรทัด แต่เมื่อมันมาถึงการดำเนินการแทรกหรืออัปเดตด้วยตารางที่มีมากกว่า 10 ฟิลด์หนึ่งสามารถรู้สึกถึงความแตกต่าง

คุณสามารถใช้ตัวดำเนินการ nameof เพื่อส่งชื่อฟิลด์ในฟังก์ชันเพื่อหลีกเลี่ยงการพิมพ์ผิด

แทน:

List < string > columns = new List < string > {
 "UserName",
 "City"
}

คุณสามารถเขียน:

List < string > columns = new List < string > {
nameof(UserEntity.UserName),
nameof(UserEntity.City),
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.