C# EF6-在SaveChanges()之前截断字符串字段以避免数据库冲突

C# EF6-在SaveChanges()之前截断字符串字段以避免数据库冲突,c#,entity-framework,C#,Entity Framework,我使用Windows服务定期在数据库中保存记录,首先使用Entity Framework 6代码。 我的一些客户端可能会根据DB约束(字符串长度冲突)发送错误数据。我的客户没有人机界面 我正在寻找一种在SaveChanges()之前截断这些字符串冲突并记录它们的方法 我的第一个想法是循环所有验证错误,并在db配置中将字符串长度与StringLengthAttribute进行比较: foreach (DbEntityValidationResult validationErrors in db.G

我使用Windows服务定期在数据库中保存记录,首先使用Entity Framework 6代码。 我的一些客户端可能会根据DB约束(字符串长度冲突)发送错误数据。我的客户没有人机界面

我正在寻找一种在SaveChanges()之前截断这些字符串冲突并记录它们的方法

我的第一个想法是循环所有验证错误,并在db配置中将字符串长度与StringLengthAttribute进行比较:

foreach (DbEntityValidationResult validationErrors in db.GetValidationErrors())
{
   foreach (DbValidationError validationError in validationErrors.ValidationErrors)
   {
      //Test if EF6 value is longer than DB max size
      //If greater, truncate it and log a warning message
   }
}
我的另一个(糟糕的)解决方案是截断数据层中的字符串字段,但它根本没有效率。这是一个只针对一个属性的糟糕示例

private string pcName;
[Required]
[StringLength(100)]
public string PCName
{
   get { return pcName; }
   set
   {
       const int stringLengthAttribute = 100; // Should be equal to StringLengthAttribute
       if (value.Length <= stringLengthAttribute)
          pcName = value;
       else
          {
             pcName = value.Substring(0, stringLengthAttribute);
             Log.Warn("PC.pcName truncated from " + value + " to " + pcName);
          }
    }
}
私有字符串pcName;
[必需]
[长度(100)]
公共字符串PCName
{
获取{return pcName;}
设置
{
const int stringLengthAttribute=100;//应等于stringLengthAttribute

if(value.Length最好的解决方案通常是在数据进入系统时修复数据。甚至不要向数据库发送坏的/未验证的数据。这是毫无意义的,因为您有相同的验证/修复代码,但情况更糟

在你写的地方

  //Test if EF6 value is longer than DB max size
  //If greater, truncate it and log a warning message
您将需要与当前指定为“坏”的代码相同的代码

另外,不要让setter修改正在设置的数据。setter不应该包含这样的逻辑,getter应该返回与设置相同的数据


相反,只设置正确的值。例如
myEntity.MyString=userInput.Truncate(200)

根本没有效率
?为什么这比发送坏数据并稍后进行修复效率低?测量可能是错误的。感谢您的回复。效率不高是因为我做了大量工作,如果DB字符串大小发生变化,我会失去代码的灵活性。:)事实上,有一种方法可以在保存验证约束之前检查它们。因此,研究更多选项可能是一个好主意。我从未发现EF实体上的验证属性有用。验证通常应该在架构上的其他地方进行。通常,验证取决于上下文,并且在验证失败时采取的操作也取决于上下文不同。例如,拒绝错误的输入似乎比默默删除一些数据更好。这些属性也不足以涵盖所有情况。所以我总是发现最好放弃它们。对于早期的EF版本,类似的问题是:好的,我明白你的意思。有没有自动处理StringLengthAttribute的解决方案?真的很简单让setter执行这样的操作是不好的。它打破了通常的假设,即
prop=val;Assert(prop==val);
。如果您想继续,您可以修改生成实体的T4模板以利用这些属性。或者,在运行时使用反射。现在我不明白:)确定沉降器警告。我必须检查我的客户端如何根据db约束验证字符串大小。字符串在本地定义(在客户端中的意思)数据库约束在服务器中定义…如果数据库大小可以不同,则属性将无效。您可以在运行时查询数据库架构以查找支持的最大长度。