有什么办法可以让代码更干净/更高效?(C#/LINQ到SQL)

有什么办法可以让代码更干净/更高效?(C#/LINQ到SQL),c#,asp.net,linq-to-sql,C#,Asp.net,Linq To Sql,我一直在为我正在开发的一个程序准备一个审计解决方案,在这个程序中,我使用LINQ进行更新/插入操作。我提出了以下解决方案(这是用于插入的代码段)(注意Tables变量包含已修改的所有表的列表-我手动将这些表添加到列表中并调用此方法): 对于每个可能的表名,代码都在继续。代码运行良好,但效率似乎相当低——每种情况下都有一个几乎相同的块。有没有更有效的方法?当然,您可以将以下代码提取到一个方法中: string NewJobString = null; Job JobDetails = (

我一直在为我正在开发的一个程序准备一个审计解决方案,在这个程序中,我使用LINQ进行更新/插入操作。我提出了以下解决方案(这是用于插入的代码段)(注意Tables变量包含已修改的所有表的列表-我手动将这些表添加到列表中并调用此方法):


对于每个可能的表名,代码都在继续。代码运行良好,但效率似乎相当低——每种情况下都有一个几乎相同的块。有没有更有效的方法?

当然,您可以将以下代码提取到一个方法中:

 string NewJobString = null;
    Job JobDetails = (Job)Table;
    var prpsJob = typeof(Job).GetProperties(b);
    foreach (var p in prpsJob)
    {
           object x = p.GetGetMethod().Invoke(Table, null);
           x = StripDate(x);
           NewJobString += p.Name + ": " + x + Environment.NewLine;
    }

public string GetProperties(Type t, BindingFlags b)
{
     StringBuilder sb = new StringBuilder();
     var prpsJob = typeof(t).GetProperties(b);
     foreach (var p in prpsJob)
     {
          object x = p.GetMethod().Invoke(Table, null);
          x = StripDate(x);
          sb.Append(p.Name + ": " + x + Environment.NewLine);
     }
     return sb.ToString()
}
吃点类似的东西

 case "Job":

   Audit(JobID, GetProperties(typeof(Job),b), "New Job created", SourceID, "", JobDetails.JobID);
   break;

据我所知,大多数重复代码都将对象的值转储到字符串中

可以使用助手方法执行此操作:

public static string DumpObject<T>(T obj)
{
    StringBuilder sb = new StringBuilder();

    var properties = typeof(T).GetProperties(
                     BindingFlags.Instance | BindingFlags.Public);

    foreach (var p in properties)
    {
        object x = p.GetGetMethod().Invoke(obj, null);
        x = StripDate(x);
        sb.Append(p.Name).Append(": ").Append(x).AppendLine();
    }

    return sb.ToString();
}

我建议您使用T4模板通过使用生成LINQ到SQL类。然后在有特殊需要的表上添加一个接口

public interface IHaveEstimation {
   DateTime GetEstimationDate();
}
在LINQDataContext.tt文件中,您可以添加一些额外的T4生成代码来检测表并将接口添加到该对象:

<#  
  string markerInterface = String.Empty;

  if (class1.Name == "Estimation")
  {
     markerInterface = "IHaveEstimation"; 
  }
#>

<#=code.Format(class1.TypeAttributes)#>partial class <#=class1.Name#>
<#=String.IsNullOrEmpty(markerInterface) ? String.Empty : String.Format(" : {0}", markerInterface) #>
{ ... }

部分类
{ ... }
在LINQDataContext.cs文件中,可以执行以下操作:

/// <summary>
/// When the database context is submitted.
/// </summary>
/// <param name="failureMode">
/// the submit failure mode
/// </param>
public override void SubmitChanges(ConflictMode failureMode)
{
  foreach (var insert in changeSet.Inserts.OfType<IHaveEstimation>())
  {
    var estimtation = insert.GetEstimationDate();
    // handle auditing, etc.
  }

  // do same for update and delete change sets
}
//
///提交数据库上下文时。
/// 
/// 
///提交失败模式
/// 
公共覆盖无效提交更改(冲突模式故障模式)
{
foreach(changeSet.Inserts.OfType()中的var insert)
{
var estimtation=insert.GetEstimationDate();
//处理审计等。
}
//对更新和删除更改集执行相同的操作
}

你真的应该使用这个答案

如果您不想序列化所有属性,我强烈建议您创建一个自定义属性,并根据它过滤列表(当然,之前要装饰属性)。在行乞时,与IL打交道是肮脏的,但这是最有效的方式。手放下了


luke

您应该能够使用Lambdas来覆盖重复代码中特定于类型的部分。这几乎是我拼凑的伪代码

void TableIsJob(Job j, BindingFlags b) {
   HandleTable("Job", j.JobID, typeof(Job).GetProperties(b),
               p=>p.GetGetMethod().Invoke(j, null));
}


void TableIsEstimation(Estimation e, BindingFlags b) {
   HandleTable("Estimation", e.EstimationID, typeof(Estimation).GetProperties(b),
       p => p.GetGetMethod().Invoke(e, null));
}

void HandleTable(string nm, int ID, PropertyInfo [] props, Func<PropertyInf, Object> i) {
       string desc = string.Join(Environment.NewLine, props.Select(p=>{
                       return string.Format("{0}: {1}", p.Name,
                                    StripDate(i(p)));
               }).ToArray());
       Audit(JobID, desc, string.Format("New {0} created", nm),
             SourceID, "", id);
}

这都是假设“高效”是指代码量,而不是执行时间。

PLINQO在DataContext中具有审计功能:审计细节:这是哪个.NET框架?
/// <summary>
/// When the database context is submitted.
/// </summary>
/// <param name="failureMode">
/// the submit failure mode
/// </param>
public override void SubmitChanges(ConflictMode failureMode)
{
  foreach (var insert in changeSet.Inserts.OfType<IHaveEstimation>())
  {
    var estimtation = insert.GetEstimationDate();
    // handle auditing, etc.
  }

  // do same for update and delete change sets
}
void TableIsJob(Job j, BindingFlags b) {
   HandleTable("Job", j.JobID, typeof(Job).GetProperties(b),
               p=>p.GetGetMethod().Invoke(j, null));
}


void TableIsEstimation(Estimation e, BindingFlags b) {
   HandleTable("Estimation", e.EstimationID, typeof(Estimation).GetProperties(b),
       p => p.GetGetMethod().Invoke(e, null));
}

void HandleTable(string nm, int ID, PropertyInfo [] props, Func<PropertyInf, Object> i) {
       string desc = string.Join(Environment.NewLine, props.Select(p=>{
                       return string.Format("{0}: {1}", p.Name,
                                    StripDate(i(p)));
               }).ToArray());
       Audit(JobID, desc, string.Format("New {0} created", nm),
             SourceID, "", id);
}
Tables.Select(t =>
{
   switch (t.ToString().Replace("Project.", ""))
   {
       case "Job":
           TableIsJob((Job)t, b);
           break;
       case "Estimation":
           TableIsEstimation((Estimation)t, b);
           break;
   }
});