如何创建多个 CRUD 方法重载?
How do I create multiple overloads of CRUD methods?
如果我有一个 class,它以某种方式表示到我的数据库中特定 table 的映射。
class 包含大约 30 个属性。
我创建了 CRUD Methods
。
我发现自己需要另一个 (UPDATE
) 方法,它应该只更新两个字段。
用简单的例子应该怎样做才好?
使用我的存在方法,填充整个对象并更新所有字段,包括我想要的两个字段? (无用功)
用另一个名称创建静态方法(但我想保留我的方法名称,因为它具有表现力)!并接受两个参数?
这取决于您对项目的优先考虑:
使用您现有的更新方法将一直更新所有内容,增加流量、IO 和处理时间(验证等...)
如果您在一个属性带有时间戳的项目中,即使值没有真正改变,它们也会更新...
如果您不介意所有这些,请始终使用您的 update() 方法。
我个人的 POV 是:创建一个新方法(具有明确的名称)。从现在开始,这将是相同的处理时间和 2 年后的思考时间,届时您将不得不更改此 class ;)
我不知道这是否是您必须做的事情,但您可以做一些事情:创建一个 SetAll 或 SetMany 或您传入 class 的另一个实例的任何方法(来源) .检查每个 属性,如果它不为空,则将目标对象的 属性 值设置为源对象的 属性 值。请注意,此策略将取决于可空类型,并假设您可以忽略传递给新 setter 方法的空值。这是一个例子:
using System;
namespace BlogPartialUpdateTrick
{
public class SomeClass
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int? HeightInches { get; set; }
public DateTime? Dob { get; set; }
public void SetAll(SomeClass source)
{
this.FirstName = source.FirstName ?? this.FirstName;
this.LastName = source.LastName ?? this.LastName;
this.HeightInches = source.HeightInches ?? this.HeightInches;
this.Dob = source.Dob ?? this.Dob;
}
public override string ToString()
{
return String.Format("fn: {0}, ln: {1}, height: {2}, DOB: {3}", FirstName ?? String.Empty, LastName ?? String.Empty,
HeightInches.HasValue ? HeightInches.Value.ToString() : "null", Dob.HasValue ? Dob.Value.ToShortDateString() : "null" );
}
}
}
在第一个代码示例中,我们有漂亮的 class SomeClass。它有 4 个属性,所有属性都可以为空。这个 class 值得注意的部分是 SetAllMethod,我可以在其中传入也是 SomeClass 类型的源对象。它将此实例的 属性 值设置为源参数中传递的值,但前提是它们不为空。这是我使用这些东西的第二个代码简介:
using System;
using System.Windows.Forms;
namespace BlogPartialUpdateTrick
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var destination = new SomeClass() { FirstName = "Freddy", LastName = "Fingers", Dob = DateTime.Parse("01/01/1970"), HeightInches = 72 };
var source = new SomeClass() { FirstName = null, LastName="Flippers", Dob = null, HeightInches = 80 };
destination.SetAll(source);
MessageBox.Show(destination.ToString());
}
}
}
创建一个目标对象,一个源对象,调用新方法,瞧!输出是这样的:
"fn: Freddy, ln: Flippers, height: 80, DOB: 1/1/1970"
您可能应该使用 Entity Framework 并让上下文为您完成。使用 EF,您将能够像这样更新实体:
try
{
var original = ObjectContext.Set<Request>().SingleOrDefault(x => x.Id.Equals(_request.Id));
if (original != null)
{
ObjectContext.Entry(original).CurrentValues.SetValues(_request);
}
return ObjectContext.SaveChanges();
}
catch (Exception ee)
{
return -1;
}
我建议按照你的第二个选项,但不需要更改名称,因为方法参数的数量在两者上都是不同的
让我们走进几个例子
我会尝试创造一个类似的情况,希望是你的情况。如果我问错了,你可以澄清一下。
类 和方法
/// <summary>
/// CLass to store properties related to database
/// </summary>
class ObjectoA
{
public string A{get; set;}
public string B{get; set;}
public string C{ get; set; }
}
/// <summary>
/// class to call method to update.
///
/// </summary>
class ObjectB
{
/// <summary>
/// update method.
/// I would go with this solution.
/// optionlay you can call the method which receive parameter of object
/// </summary>
/// <param name="A"> Object with properties mapped to database</param>
/// <param name="updatetwoproperties">Optional paramneter to decide which update to run.
/// the default value should be for update that run most. For your need if you want to create an update methods for other
/// two sets of parameter a suggest you create an Enum and pass this enum as optional parameter instead of bool parameter or you
/// can pass as string and map each string value to specific update inside. IF YOU NEED EXAMPLE
/// REPLAY ON COMMENTS</param>
/// <returns></returns>
public bool update(ObjectoA A, bool updatetwoproperties=false)
{
//method implementation
if (updatetwoproperties)
{
//implement a update to all field
}
else
{
//implement update just to two field
}
return true;
}
/// <summary>
/// update method based on parameter to update
/// </summary>
/// <param name="a">this properties is mapped on database</param>
/// <param name="b">this propertie is mapped on database</param>
/// <returns></returns>
public bool update(string a, string b)
{
//method implementation e validate the return value
return true;
}
}
/// <summary>
/// I don't suggest to use this solution because
/// it will add a method on string type while this method isn't related to string
/// I just added here as a workaround for you.
/// </summary>
public 静态 class ObjectC
{
public static bool update(这个字符串a,字符串b)
{
//更新和验证 return 值的实现
return 是的;
}
}
调用方法及说明
static void Main(string[] args)
{
ObjectB B = new ObjectB(); //Class with methods
ObjectoA A = new ObjectoA(); //object with properties
#region Using Optional parameter to decide which update to run
//Calling a method to update all columns
B.update(A);
//Calling a method to update two columns
B.update(A, true);
#endregion
#region Using polymorphism to update
//Calling a method to update all columns
B.update(A);
//Update only using paramenter
B.update(A.B, A.C);
#endregion
//NOT RECOMMEND BECAUSE THIS UPDATE ISN'T RELATED TO STRING TYPE
#region Using extension method to update
//Calling a method to update all columns
B.update(A);
//using the extension method on variable type
A.B.update(A.C);
#endregion
//WE COULD USE EXTENSION METHOD ON YOUR OBJECT BUT IT WILL FAIL BECAUSE WE ALREADY AS UPDATE METHOD ON CLASS
//IF YOU WANT TO SEE HOW JUST REPLAY
}
我建议您在决定使用哪个更新的方法中添加可选参数
我会创建两个单独的接口并为每个接口创建重载函数。我会根据用途对属性进行分组,比如我希望状态与其他常见属性分开更新一段时间。
public interface ICommonProperties
{
public string P1{get; set;}
public string P2{get; set;}
public string P3{ get; set; }
}
public interface ITrackable
{
public string Status{get; set;}
}
public class FinalClass : ICommonProperties, ITrackable
{
public string P1{get; set;}
public string P2{get; set;}
public string P3{get; set;}
public string Status{get; set;}
}
public class FinalClassOperations
{
public void Update(FinalClass finalClassInstance) { }; //Updates everything
public void Update(ICommonProperties finalClassInstance) { }; //Updates only ICommonProperties
public void Update(ITrackable finalClassInstance) { }; //updates only Status.
}
此外,如果您愿意,可以创建一个单独的 class 来仅更新状态,这仍然适合:
public class Tracker : ITrackable{
public string Status{get; set;}
}
但是,是的,如果这两个属性不能逻辑上分开,我不会那样做并将它们放在一起。
如果我有一个 class,它以某种方式表示到我的数据库中特定 table 的映射。 class 包含大约 30 个属性。
我创建了 CRUD Methods
。
我发现自己需要另一个 (UPDATE
) 方法,它应该只更新两个字段。
用简单的例子应该怎样做才好?
使用我的存在方法,填充整个对象并更新所有字段,包括我想要的两个字段? (无用功)
用另一个名称创建静态方法(但我想保留我的方法名称,因为它具有表现力)!并接受两个参数?
这取决于您对项目的优先考虑: 使用您现有的更新方法将一直更新所有内容,增加流量、IO 和处理时间(验证等...) 如果您在一个属性带有时间戳的项目中,即使值没有真正改变,它们也会更新...
如果您不介意所有这些,请始终使用您的 update() 方法。
我个人的 POV 是:创建一个新方法(具有明确的名称)。从现在开始,这将是相同的处理时间和 2 年后的思考时间,届时您将不得不更改此 class ;)
我不知道这是否是您必须做的事情,但您可以做一些事情:创建一个 SetAll 或 SetMany 或您传入 class 的另一个实例的任何方法(来源) .检查每个 属性,如果它不为空,则将目标对象的 属性 值设置为源对象的 属性 值。请注意,此策略将取决于可空类型,并假设您可以忽略传递给新 setter 方法的空值。这是一个例子:
using System;
namespace BlogPartialUpdateTrick
{
public class SomeClass
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int? HeightInches { get; set; }
public DateTime? Dob { get; set; }
public void SetAll(SomeClass source)
{
this.FirstName = source.FirstName ?? this.FirstName;
this.LastName = source.LastName ?? this.LastName;
this.HeightInches = source.HeightInches ?? this.HeightInches;
this.Dob = source.Dob ?? this.Dob;
}
public override string ToString()
{
return String.Format("fn: {0}, ln: {1}, height: {2}, DOB: {3}", FirstName ?? String.Empty, LastName ?? String.Empty,
HeightInches.HasValue ? HeightInches.Value.ToString() : "null", Dob.HasValue ? Dob.Value.ToShortDateString() : "null" );
}
}
}
在第一个代码示例中,我们有漂亮的 class SomeClass。它有 4 个属性,所有属性都可以为空。这个 class 值得注意的部分是 SetAllMethod,我可以在其中传入也是 SomeClass 类型的源对象。它将此实例的 属性 值设置为源参数中传递的值,但前提是它们不为空。这是我使用这些东西的第二个代码简介:
using System;
using System.Windows.Forms;
namespace BlogPartialUpdateTrick
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var destination = new SomeClass() { FirstName = "Freddy", LastName = "Fingers", Dob = DateTime.Parse("01/01/1970"), HeightInches = 72 };
var source = new SomeClass() { FirstName = null, LastName="Flippers", Dob = null, HeightInches = 80 };
destination.SetAll(source);
MessageBox.Show(destination.ToString());
}
}
}
创建一个目标对象,一个源对象,调用新方法,瞧!输出是这样的:
"fn: Freddy, ln: Flippers, height: 80, DOB: 1/1/1970"
您可能应该使用 Entity Framework 并让上下文为您完成。使用 EF,您将能够像这样更新实体:
try
{
var original = ObjectContext.Set<Request>().SingleOrDefault(x => x.Id.Equals(_request.Id));
if (original != null)
{
ObjectContext.Entry(original).CurrentValues.SetValues(_request);
}
return ObjectContext.SaveChanges();
}
catch (Exception ee)
{
return -1;
}
我建议按照你的第二个选项,但不需要更改名称,因为方法参数的数量在两者上都是不同的 让我们走进几个例子
我会尝试创造一个类似的情况,希望是你的情况。如果我问错了,你可以澄清一下。
类 和方法
/// <summary>
/// CLass to store properties related to database
/// </summary>
class ObjectoA
{
public string A{get; set;}
public string B{get; set;}
public string C{ get; set; }
}
/// <summary>
/// class to call method to update.
///
/// </summary>
class ObjectB
{
/// <summary>
/// update method.
/// I would go with this solution.
/// optionlay you can call the method which receive parameter of object
/// </summary>
/// <param name="A"> Object with properties mapped to database</param>
/// <param name="updatetwoproperties">Optional paramneter to decide which update to run.
/// the default value should be for update that run most. For your need if you want to create an update methods for other
/// two sets of parameter a suggest you create an Enum and pass this enum as optional parameter instead of bool parameter or you
/// can pass as string and map each string value to specific update inside. IF YOU NEED EXAMPLE
/// REPLAY ON COMMENTS</param>
/// <returns></returns>
public bool update(ObjectoA A, bool updatetwoproperties=false)
{
//method implementation
if (updatetwoproperties)
{
//implement a update to all field
}
else
{
//implement update just to two field
}
return true;
}
/// <summary>
/// update method based on parameter to update
/// </summary>
/// <param name="a">this properties is mapped on database</param>
/// <param name="b">this propertie is mapped on database</param>
/// <returns></returns>
public bool update(string a, string b)
{
//method implementation e validate the return value
return true;
}
}
/// <summary>
/// I don't suggest to use this solution because
/// it will add a method on string type while this method isn't related to string
/// I just added here as a workaround for you.
/// </summary>
public 静态 class ObjectC { public static bool update(这个字符串a,字符串b) { //更新和验证 return 值的实现 return 是的; } }
调用方法及说明
static void Main(string[] args)
{
ObjectB B = new ObjectB(); //Class with methods
ObjectoA A = new ObjectoA(); //object with properties
#region Using Optional parameter to decide which update to run
//Calling a method to update all columns
B.update(A);
//Calling a method to update two columns
B.update(A, true);
#endregion
#region Using polymorphism to update
//Calling a method to update all columns
B.update(A);
//Update only using paramenter
B.update(A.B, A.C);
#endregion
//NOT RECOMMEND BECAUSE THIS UPDATE ISN'T RELATED TO STRING TYPE
#region Using extension method to update
//Calling a method to update all columns
B.update(A);
//using the extension method on variable type
A.B.update(A.C);
#endregion
//WE COULD USE EXTENSION METHOD ON YOUR OBJECT BUT IT WILL FAIL BECAUSE WE ALREADY AS UPDATE METHOD ON CLASS
//IF YOU WANT TO SEE HOW JUST REPLAY
}
我建议您在决定使用哪个更新的方法中添加可选参数
我会创建两个单独的接口并为每个接口创建重载函数。我会根据用途对属性进行分组,比如我希望状态与其他常见属性分开更新一段时间。
public interface ICommonProperties
{
public string P1{get; set;}
public string P2{get; set;}
public string P3{ get; set; }
}
public interface ITrackable
{
public string Status{get; set;}
}
public class FinalClass : ICommonProperties, ITrackable
{
public string P1{get; set;}
public string P2{get; set;}
public string P3{get; set;}
public string Status{get; set;}
}
public class FinalClassOperations
{
public void Update(FinalClass finalClassInstance) { }; //Updates everything
public void Update(ICommonProperties finalClassInstance) { }; //Updates only ICommonProperties
public void Update(ITrackable finalClassInstance) { }; //updates only Status.
}
此外,如果您愿意,可以创建一个单独的 class 来仅更新状态,这仍然适合:
public class Tracker : ITrackable{
public string Status{get; set;}
}
但是,是的,如果这两个属性不能逻辑上分开,我不会那样做并将它们放在一起。