using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ScaffoldDesignerPlugin
{
public class ScaffoldDesigner
{
#region 命令系统 - 完全修正参数顺序问题
// 正确使用CommandMethod特性
[CommandMethod("DesignScaffold", CommandFlags.Modal,
"DS", "SCAFF", "SD")]
public void DesignScaffold()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null)
{
Application.ShowAlertDialog("没有活动文档!");
return;
}
Editor ed = doc.Editor;
Database db = doc.Database;
try
{
// 提示用户选择梁图元
PromptSelectionOptions selOpts = new PromptSelectionOptions();
selOpts.MessageForAdding = "请选择梁图元: ";
PromptSelectionResult selResult = ed.GetSelection(selOpts);
if (selResult.Status != PromptStatus.OK)
{
ed.WriteMessage("\n选择已取消.");
return;
}
// 识别梁数据
List<BeamData> beams = IdentifyBeams(db, selResult.Value);
if (beams.Count == 0)
{
ed.WriteMessage("\n未识别到有效梁数据!");
return;
}
// 安全计算与网格生成
List<ScaffoldGrid> grids = CalculateAndGenerateGrids(beams, _currentMaterial);
// 绘制网格
DrawContinuousGrids(db, beams, grids);
// 生成计算书
GenerateCalculationReport(ed, beams, grids);
ed.WriteMessage("\n脚手架设计完成!");
}
catch (Autodesk.AutoCAD.Runtime.Exception acadEx)
{
ed.WriteMessage($"\nAutoCAD错误: {acadEx.Message}");
}
catch (System.Exception sysEx)
{
ed.WriteMessage($"\n系统错误: {sysEx.Message}\n{sysEx.StackTrace}");
}
}
// 正确使用CommandMethod特性
[CommandMethod("SetScaffoldMaterial", CommandFlags.Modal,
"SSM", "MATERIAL")]
public void SetScaffoldMaterial()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null)
{
Application.ShowAlertDialog("没有活动文档!");
return;
}
Editor ed = doc.Editor;
// 创建材料选择选项
PromptKeywordOptions pko = new PromptKeywordOptions("\n选择材料类型:");
pko.Keywords.Add("Steel", "S", "Steel (钢材)");
pko.Keywords.Add("Aluminum", "A", "Aluminum (铝材)");
pko.Keywords.Add("Wood", "W", "Wood (木材)");
pko.AllowNone = false;
pko.AppendKeywordsToMessage = true;
PromptResult pr = ed.GetKeywords(pko);
if (pr.Status == PromptStatus.OK)
{
switch (pr.StringResult)
{
case "Steel":
_currentMaterial = _steelMaterial;
ed.WriteMessage("\n已选择钢材参数");
break;
case "Aluminum":
_currentMaterial = _aluminumMaterial;
ed.WriteMessage("\n已选择铝材参数");
break;
case "Wood":
_currentMaterial = _woodMaterial;
ed.WriteMessage("\n已选择木材参数");
break;
}
}
else
{
ed.WriteMessage("\n材料选择已取消.");
}
}
// 正确使用CommandMethod特性
[CommandMethod("UpdateScaffoldGrid", CommandFlags.Modal,
"USG", "UPDATE")]
public void UpdateScaffoldGrid()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null)
{
Application.ShowAlertDialog("没有活动文档!");
return;
}
Editor ed = doc.Editor;
Database db = doc.Database;
try
{
// 选择已绘制的脚手架网格
PromptSelectionOptions selOpts = new PromptSelectionOptions();
selOpts.MessageForAdding = "选择要更新的脚手架网格: ";
PromptSelectionResult selResult = ed.GetSelection(selOpts);
if (selResult.Status != PromptStatus.OK)
{
ed.WriteMessage("\n选择已取消.");
return;
}
// 获取关联的梁数据
List<BeamData> beams = GetBeamsFromGrids(db, selResult.Value);
if (beams.Count == 0)
{
ed.WriteMessage("\n未找到关联梁数据!");
return;
}
// 重新计算网格
List<ScaffoldGrid> grids = CalculateAndGenerateGrids(beams, _currentMaterial);
// 更新网格
UpdateGrids(db, selResult.Value, grids);
ed.WriteMessage("\n脚手架网格已更新!");
}
catch (Autodesk.AutoCAD.Runtime.Exception acadEx)
{
ed.WriteMessage($"\nAutoCAD错误: {acadEx.Message}");
}
catch (System.Exception sysEx)
{
ed.WriteMessage($"\n系统错误: {sysEx.Message}");
}
}
#endregion
#region 核心数据结构
public class BeamData
{
public ObjectId ObjectId { get; set; }
public Point3d Position { get; set; }
public double Width { get; set; } // mm
public double Height { get; set; } // mm
public double Length { get; set; } // mm
public Vector3d Direction { get; set; }
public bool IsMainBeam { get; set; } = true;
public double ConcreteDensity { get; set; } = 25.0; // kN/m³
public Extents3d Extents { get; set; }
}
public class ScaffoldGrid
{
public Point3d BasePoint { get; set; }
public Vector3d Direction { get; set; }
public double TransverseSpacing { get; set; } // mm
public double AlongSpacing { get; set; } // mm
public double SafetyFactor { get; set; }
public double MaxDeflection { get; set; } // mm
public double MaxStress { get; set; } // MPa
public ObjectId AssociatedBeamId { get; set; }
}
public struct MaterialParams
{
public double Modulus; // 弹性模量 (MPa)
public double Strength; // 抗弯强度 (MPa)
public double SectionModulus; // 截面模量 (mm³)
public double MomentOfInertia; // 截面惯性矩 (mm⁴)
public double ConstructionLoad; // 施工荷载 (kN/m²)
public double FormworkWeight; // 模板自重 (kN/m²)
public double StructureImportanceFactor;
public double PermanentLoadFactor;
public double VariableLoadFactor;
}
#endregion
#region 核心功能实现 - 完全修正错误
private List<BeamData> IdentifyBeams(Database db, SelectionSet selectionSet)
{
List<BeamData> beams = new List<BeamData>();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
foreach (ObjectId objId in selectionSet.GetObjectIds())
{
Entity ent = tr.GetObject(objId, OpenMode.ForRead) as Entity;
if (ent == null) continue;
try
{
// 获取实体包围盒
Extents3d ext = ent.GeometricExtents;
// 计算中点
double midX = (ext.MinPoint.X + ext.MaxPoint.X) * 0.5;
double midY = (ext.MinPoint.Y + ext.MaxPoint.Y) * 0.5;
double midZ = (ext.MinPoint.Z + ext.MaxPoint.Z) * 0.5;
Point3d midpoint = new Point3d(midX, midY, midZ);
// 计算梁方向
Vector3d direction = Vector3d.XAxis;
if (ent is Line line)
{
Vector3d lineDirection = line.EndPoint - line.StartPoint;
direction = lineDirection.GetNormal();
}
else if (ent is Polyline polyline)
{
// 对于多段线,取首尾点方向
Point3d start = polyline.GetPoint3dAt(0);
Point3d end = polyline.GetPoint3dAt(polyline.NumberOfVertices - 1);
direction = (end - start).GetNormal();
}
beams.Add(new BeamData {
ObjectId = objId,
Position = midpoint,
Width = Math.Round(ext.MaxPoint.X - ext.MinPoint.X, 2),
Height = Math.Round(ext.MaxPoint.Y - ext.MinPoint.Y, 2),
Length = Math.Round(ext.MaxPoint.Z - ext.MinPoint.Z, 2),
Direction = direction,
Extents = ext
});
}
catch (System.Exception sysEx)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
$"\n处理对象 {objId} 时出错: {sysEx.Message}");
}
}
tr.Commit();
}
return beams;
}
private List<ScaffoldGrid> CalculateAndGenerateGrids(List<BeamData> beams, MaterialParams material)
{
List<ScaffoldGrid> grids = new List<ScaffoldGrid>();
foreach (BeamData beam in beams)
{
try
{
// 计算混凝土自重 (kN/m)
double beamArea = (beam.Width / 1000) * (beam.Height / 1000); // m²
double concreteWeight = beam.ConcreteDensity * beamArea;
// 计算模板及龙骨自重 (kN/m)
double formworkWeight = material.FormworkWeight * (beam.Width / 1000);
// 计算施工荷载 (kN/m)
double constructionLoad = material.ConstructionLoad * (beam.Width / 1000);
// 计算荷载组合
double totalLoad = material.StructureImportanceFactor *
(material.PermanentLoadFactor * (concreteWeight + formworkWeight) +
material.VariableLoadFactor * constructionLoad);
// 转换为线荷载 (N/mm)
double q = totalLoad * 1000; // kN/m -> N/m -> 转换为N/mm (除以1000转为N/mm)
// 计算最大允许跨度 (基于抗弯强度)
double L_bending = Math.Sqrt((8 * material.SectionModulus * material.Strength) / q);
// 计算最大允许跨度 (基于挠度控制)
double L_deflection = Math.Pow((384 * material.Modulus * material.MomentOfInertia * beam.Length) /
(5 * q * Math.Pow(beam.Length, 3) * 1000), 1.0/4); // 考虑挠度限值
// 取较小值作为实际间距 (mm)
double spacing = Math.Min(L_bending, L_deflection) * 1000;
spacing = StandardizeSpacing(spacing);
// 计算安全系数
double M_max = q * Math.Pow(spacing/1000, 2) / 8; // 最大弯矩 (N·mm)
double maxStress = M_max / material.SectionModulus; // 最大应力 (MPa)
double safetyFactor = material.Strength / maxStress;
// 计算最大挠度
double maxDeflection = (5 * q * Math.Pow(spacing/1000, 4)) /
(384 * material.Modulus * material.MomentOfInertia) * 1000; // mm
grids.Add(new ScaffoldGrid {
BasePoint = beam.Position,
Direction = beam.Direction,
TransverseSpacing = spacing,
AlongSpacing = 1200, // 标准纵向间距
SafetyFactor = safetyFactor,
MaxStress = maxStress,
MaxDeflection = maxDeflection,
AssociatedBeamId = beam.ObjectId
});
}
catch (System.Exception sysEx)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
$"\n计算梁 {beam.ObjectId} 时出错: {sysEx.Message}");
}
}
return grids;
}
private double StandardizeSpacing(double spacing)
{
double[] standard = { 300, 600, 900, 1200, 1500, 1800 };
return standard.OrderBy(s => Math.Abs(s - spacing)).First();
}
private void DrawContinuousGrids(Database db, List<BeamData> beams, List<ScaffoldGrid> grids)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
// 创建图层 - 修正为"盘扣轴网"
ObjectId layerId = CreateScaffoldLayer(db, tr, "盘扣轴网");
// 绘制网格
foreach (ScaffoldGrid grid in grids)
{
DrawGrid(btr, grid, layerId, tr);
}
tr.Commit();
}
}
private void DrawGrid(BlockTableRecord btr, ScaffoldGrid grid, ObjectId layerId, Transaction tr)
{
Vector3d perpDir = grid.Direction.CrossProduct(Vector3d.ZAxis).GetNormal();
// 横向网格线
for (int i = -2; i <= 2; i++)
{
double offset = i * grid.TransverseSpacing;
Point3d start = grid.BasePoint + (-grid.Direction * 5000) + (perpDir * offset);
Point3d end = grid.BasePoint + (grid.Direction * 5000) + (perpDir * offset);
Line line = new Line(start, end);
SetupGridEntity(line, layerId, i == 0);
btr.AppendEntity(line);
tr.AddNewlyCreatedDBObject(line, true);
// 存储网格数据到扩展数据
SetGridXData(line, grid);
}
// 纵向网格线
for (int i = -5; i <= 5; i++)
{
double offset = i * grid.AlongSpacing;
Point3d start = grid.BasePoint + (-perpDir * 5000) + (grid.Direction * offset);
Point3d end = grid.BasePoint + (perpDir * 5000) + (grid.Direction * offset);
Line line = new Line(start, end);
SetupGridEntity(line, layerId, false);
btr.AppendEntity(line);
tr.AddNewlyCreatedDBObject(line, true);
// 存储网格数据到扩展数据
SetGridXData(line, grid);
}
}
private void SetGridXData(Entity ent, ScaffoldGrid grid)
{
// 创建扩展数据
ResultBuffer rb = new ResultBuffer();
// 使用句柄代替ObjectId
rb.Add(new TypedValue((int)DxfCode.Handle, grid.AssociatedBeamId.Handle.ToString()));
// 存储网格参数
rb.Add(new TypedValue((int)DxfCode.Real, grid.TransverseSpacing));
rb.Add(new TypedValue((int)DxfCode.Real, grid.AlongSpacing));
rb.Add(new TypedValue((int)DxfCode.Real, grid.SafetyFactor));
ent.XData = rb;
}
private void SetupGridEntity(Entity ent, ObjectId layerId, bool isPrimary)
{
ent.LayerId = layerId;
ent.ColorIndex = isPrimary ? 1 : 2; // 红色为主网格
ent.Linetype = "Continuous";
}
// 添加图层名称参数
private ObjectId CreateScaffoldLayer(Database db, Transaction tr, string layerName)
{
LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
if (!lt.Has(layerName))
{
lt.UpgradeOpen();
LayerTableRecord ltr = new LayerTableRecord {
Name = layerName,
Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(
Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 7) // 白色
};
lt.Add(ltr);
tr.AddNewlyCreatedDBObject(ltr, true);
}
return lt[layerName];
}
private void GenerateCalculationReport(Editor ed, List<BeamData> beams, List<ScaffoldGrid> grids)
{
try
{
ed.WriteMessage("\n==== 支模架设计计算书 ====");
ed.WriteMessage($"\n设计时间: {DateTime.Now:yyyy-MM-dd HH:mm}");
ed.WriteMessage($"\n设计规范: JGJ/T231-2021");
ed.WriteMessage($"\n使用材料: {GetMaterialName(_currentMaterial)}");
// 梁信息汇总
ed.WriteMessage("\n\n=== 梁信息 ===");
foreach (var beam in beams)
{
ed.WriteMessage($"\n梁 {beams.IndexOf(beam)+1}: " +
$"{beam.Width}×{beam.Height}mm, " +
$"长度: {beam.Length}mm, " +
$"{(beam.IsMainBeam ? "主梁" : "次梁")}");
}
// 设计结果
ed.WriteMessage("\n\n=== 设计结果 ===");
ed.WriteMessage($"\n{"梁号",-5} {"横向间距(mm)",-12} {"安全系数",-10} {"最大挠度(mm)",-12} {"最大应力(MPa)",-12}");
for (int i = 0; i < grids.Count; i++)
{
ed.WriteMessage($"\n{i+1,-5} {grids[i].TransverseSpacing,-12:F0} {grids[i].SafetyFactor,-10:F2} " +
$"{grids[i].MaxDeflection,-12:F2} {grids[i].MaxStress,-12:F2}");
}
// 规范检查
double minSafety = grids.Min(g => g.SafetyFactor);
ed.WriteMessage(minSafety >= 1.5
? "\n\n✓ 所有网格安全系数均满足规范要求 (≥1.5)"
: $"\n\n⚠ 警告: 最小安全系数 {minSafety:F2} 低于规范要求!");
}
catch (System.Exception sysEx)
{
ed.WriteMessage($"\n生成计算书时出错: {sysEx.Message}");
}
}
private string GetMaterialName(MaterialParams material)
{
if (material.Equals(_steelMaterial)) return "钢材";
if (material.Equals(_aluminumMaterial)) return "铝材";
if (material.Equals(_woodMaterial)) return "木材";
return "未知材料";
}
private List<BeamData> GetBeamsFromGrids(Database db, SelectionSet gridSet)
{
List<BeamData> beams = new List<BeamData>();
HashSet<Handle> processedBeams = new HashSet<Handle>();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
foreach (ObjectId gridId in gridSet.GetObjectIds())
{
try
{
Entity ent = tr.GetObject(gridId, OpenMode.ForRead) as Entity;
if (ent == null) continue;
// 获取扩展数据中的梁句柄
ResultBuffer rb = ent.XData;
if (rb != null)
{
foreach (TypedValue tv in rb)
{
if (tv.TypeCode == (int)DxfCode.Handle)
{
Handle beamHandle = new Handle(Convert.ToInt64(tv.Value.ToString(), 16));
// 避免重复处理同一个梁
if (processedBeams.Contains(beamHandle)) continue;
processedBeams.Add(beamHandle);
// 通过句柄获取ObjectId
ObjectId beamId = db.GetObjectId(false, beamHandle, 0);
if (!beamId.IsNull)
{
Entity beamEnt = tr.GetObject(beamId, OpenMode.ForRead) as Entity;
if (beamEnt != null)
{
// 重新识别梁数据
beams.Add(IdentifyBeam(beamEnt));
}
}
}
}
}
}
catch (System.Exception sysEx)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
$"\n处理网格 {gridId} 时出错: {sysEx.Message}");
}
}
tr.Commit();
}
return beams;
}
private BeamData IdentifyBeam(Entity beamEnt)
{
Extents3d ext = beamEnt.GeometricExtents;
double midX = (ext.MinPoint.X + ext.MaxPoint.X) * 0.5;
double midY = (ext.MinPoint.Y + ext.MaxPoint.Y) * 0.5;
double midZ = (ext.MinPoint.Z + ext.MaxPoint.Z) * 0.5;
Point3d midpoint = new Point3d(midX, midY, midZ);
Vector3d direction = Vector3d.XAxis;
if (beamEnt is Line line)
{
Vector3d lineDirection = line.EndPoint - line.StartPoint;
direction = lineDirection.GetNormal();
}
else if (beamEnt is Polyline polyline)
{
// 对于多段线,取首尾点方向
Point3d start = polyline.GetPoint3dAt(0);
Point3d end = polyline.GetPoint3dAt(polyline.NumberOfVertices - 1);
direction = (end - start).GetNormal();
}
return new BeamData {
ObjectId = beamEnt.ObjectId,
Position = midpoint,
Width = Math.Round(ext.MaxPoint.X - ext.MinPoint.X, 2),
Height = Math.Round(ext.MaxPoint.Y - ext.MinPoint.Y, 2),
Length = Math.Round(ext.MaxPoint.Z - ext.MinPoint.Z, 2),
Direction = direction,
Extents = ext
};
}
private void UpdateGrids(Database db, SelectionSet gridSet, List<ScaffoldGrid> newGrids)
{
// 按梁ID分组网格
var gridDict = newGrids.ToDictionary(g => g.AssociatedBeamId);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
foreach (ObjectId gridId in gridSet.GetObjectIds())
{
Entity ent = tr.GetObject(gridId, OpenMode.ForWrite) as Entity;
if (ent == null) continue;
// 获取关联梁句柄
Handle beamHandle = GetAssociatedBeamHandle(ent);
if (beamHandle.IsNull) continue;
// 查找对应的新网格
ObjectId beamId = db.GetObjectId(false, beamHandle, 0);
if (!gridDict.TryGetValue(beamId, out ScaffoldGrid grid))
continue;
// 更新网格位置
Vector3d perpDir = grid.Direction.CrossProduct(Vector3d.ZAxis).GetNormal();
if (ent is Line line)
{
// 判断网格类型 (横向/纵向)
bool isTransverse = line.ColorIndex == 1;
if (isTransverse) // 横向网格
{
// 计算偏移索引
double offset = (line.StartPoint - grid.BasePoint).DotProduct(perpDir);
int index = (int)Math.Round(offset / grid.TransverseSpacing);
// 更新位置
line.StartPoint = grid.BasePoint +
(-grid.Direction * 5000) +
(perpDir * (index * grid.TransverseSpacing));
line.EndPoint = grid.BasePoint +
(grid.Direction * 5000) +
(perpDir * (index * grid.TransverseSpacing));
}
else // 纵向网格
{
// 计算偏移索引
double offset = (line.StartPoint - grid.BasePoint).DotProduct(grid.Direction);
int index = (int)Math.Round(offset / grid.AlongSpacing);
// 更新位置
line.StartPoint = grid.BasePoint +
(-perpDir * 5000) +
(grid.Direction * (index * grid.AlongSpacing));
line.EndPoint = grid.BasePoint +
(perpDir * 5000) +
(grid.Direction * (index * grid.AlongSpacing));
}
}
// 更新扩展数据
UpdateGridXData(ent, grid);
}
tr.Commit();
}
}
private Handle GetAssociatedBeamHandle(Entity gridEnt)
{
ResultBuffer rb = gridEnt.XData;
if (rb == null) return new Handle();
foreach (TypedValue tv in rb)
{
if (tv.TypeCode == (int)DxfCode.Handle)
{
return new Handle(Convert.ToInt64(tv.Value.ToString(), 16));
}
}
return new Handle();
}
private void UpdateGridXData(Entity ent, ScaffoldGrid grid)
{
// 创建扩展数据
ResultBuffer rb = new ResultBuffer();
// 使用句柄代替ObjectId
rb.Add(new TypedValue((int)DxfCode.Handle, grid.AssociatedBeamId.Handle.ToString()));
// 存储网格参数
rb.Add(new TypedValue((int)DxfCode.Real, grid.TransverseSpacing));
rb.Add(new TypedValue((int)DxfCode.Real, grid.AlongSpacing));
rb.Add(new TypedValue((int)DxfCode.Real, grid.SafetyFactor));
ent.XData = rb;
}
#endregion
#region 材料参数
// 钢材参数
private static readonly MaterialParams _steelMaterial = new MaterialParams
{
Modulus = 2.06e5,
Strength = 205,
SectionModulus = 15200,
MomentOfInertia = 91200,
ConstructionLoad = 2.5,
FormworkWeight = 0.3,
StructureImportanceFactor = 1.0,
PermanentLoadFactor = 1.2,
VariableLoadFactor = 1.4
};
// 铝材参数
private static readonly MaterialParams _aluminumMaterial = new MaterialParams
{
Modulus = 0.69e5,
Strength = 110,
SectionModulus = 10200,
MomentOfInertia = 61200,
ConstructionLoad = 2.0,
FormworkWeight = 0.2,
StructureImportanceFactor = 1.0,
PermanentLoadFactor = 1.2,
VariableLoadFactor = 1.4
};
// 木材参数
private static readonly MaterialParams _woodMaterial = new MaterialParams
{
Modulus = 0.1e5,
Strength = 15,
SectionModulus = 5400,
MomentOfInertia = 32400,
ConstructionLoad = 1.5,
FormworkWeight = 0.15,
StructureImportanceFactor = 1.0,
PermanentLoadFactor = 1.2,
VariableLoadFactor = 1.4
};
// 当前使用的材料
private static MaterialParams _currentMaterial = _steelMaterial;
#endregion
}
}
CS1503参数2:无法从“Autodesk.AutoCAD.Runtime.CommandFlags"转换为“string
CS1503参数4:无法从“string”转换为“Autodesk.AutoCAD.Runtime.CommandFlags”
CS1503参数5:无法从string转换为“System.Type”
CS1503参数2:无法从“Autodesk.AutoCAD.Runtime.CommandFlags"转换为“string
CS1503参数4:无法从string”转换为“Autodesk.AutoCAD.Runtime.CommandFlags'
CS1503参数2:无法从“Autodesk.AutoCAD.Runtime.CommandFlags"转换为“string
CS1503参数4:无法从“string”转换为“Autodesk.AutoCAD.Runtime.CommandFlags'
CS1061“Handle”未包含”IsNull”的定义,并且找不到可接受第一个“Handle”类型参数的可访问扩展方法“IsNull”(是否缺少using 指令或程序集引用?)
最新发布