gpt4 book ai didi

.net - EF SaveChanges 不调用 Validate (IValidatableObject)

转载 作者:行者123 更新时间:2023-12-04 05:27:09 26 4
gpt4 key购买 nike

默认情况下,EF 在生成对象时使用 EntityObject。我已经修改它以使用我自己的 AbstractEntityObject 类。这样做时,我添加了 IValidatableObject,因为当您调用 context.SaveChanges() 时,我的印象是它会自动调用 Validate 并抛出异常。

这是我所拥有的:

public abstract class AbstractEntityObject : EntityObject, IValidatableObject
{
private readonly DBTable table;

protected AbstractEntityObject(DBTable table)
{
this.table = table;
}

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
List<OITValidationResult> results = new List<OITValidationResult>();
List<PropertyInfo> properties = new List<PropertyInfo>(GetType().GetProperties());

foreach (DBField field in table.GetFields())
{
foreach (PropertyInfo prop in properties)
if (StringUtilities.EqualsIgnoreCase(field.FieldName, prop.Name))
{
results.AddRange(field.Validate(prop.GetValue(this, null)));
results.AddRange(AdditionalValidation(field, prop));
properties.Remove(prop);
break;
}
}

return results;
}

public abstract List<OITValidationResult> AdditionalValidation(DBField field, PropertyInfo prop);
}

public abstract class AbstractTLMSEntityObject : AbstractEntityObject
{
protected AbstractTLMSEntityObject(DBTable table)
: base(table)
{
}

public override List<OITValidationResult> AdditionalValidation(DBField field, PropertyInfo prop)
{
List<OITValidationResult> results = new List<OITValidationResult>();

if (!EntityState.Equals(EntityState.Unchanged))
{
if (StringUtilities.EqualsIgnoreCase(field.FieldName, "userid"))
prop.SetValue(this, TLMSDB.User.UserName, null);
else if (StringUtilities.EqualsIgnoreCase(prop.Name, "dtmod"))
prop.SetValue(this, DateTime.Now, null);
}

OITValidationResult additionalResult = AdditionalValidation(field.Field);
if (additionalResult != null)
results.Add(additionalResult);

return results;
}

/* By default there is no additional validation, subclasses should override this if they need additional validation */
public virtual OITValidationResult AdditionalValidation(Enum field)
{
return null;
}
}

然后,我有子类,它是一个部分类以及 EF 创建的类:
public partial class CSDCrud
{
public enum Fields
{
RECEIPT_NUMBER,
GRANT_ID,
GRANT_FUND,
TOTAL_ACRES
}

public CSDCrud() : base(CSDCrudDAO.Instance.Table)
{
}

public static String GetDataPropertyName(Enum field)
{
return CSDCrudDAO.Instance.Table.GetField(field).FieldName;
}
}

由于我在 .tt 文件中更改了它,CSDCrud 从 AbstractTLMSEntityObject 继承。

现在这就是它变得奇怪的地方。我已经设置好 DBField(在父类中引用)对数据进行自我验证。在这种情况下,我已经设置了它,所以如果需要receipt_number,因此会失败并抛出异常......实际上,会发生以下情况......
List<OITValidationResult> results = (List<OITValidationResult>)crudObject.Validate(null);
try
{
CommonEntityManager.GetContext().CrudSet.AddObject(crudObject);
CommonEntityManager.GetContext().SaveChanges();
return true;
}
catch (Exception ex)
{
return false;
}

正如预期的那样,结果包含 1 个项目,这是正确的错误......但是 SaveChanges 将它保存得很好,没有抛出异常......我错过了什么?

编辑:我应该注意,显然我可以使用 SavingChanges 事件添加到我自己的处理程序中,但我希望使用预先存在的基础结构。
static void context_SavingChanges(object sender, EventArgs e)
{
foreach (ObjectStateEntry ose in context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
{
List<ValidationResult> results = new List<ValidationResult>(((IValidatableObject)ose.Entity).Validate(null));
if (results.Count > 0)
throw new CustomException(results);
}

foreach (ObjectStateEntry ose in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added))
{
List<ValidationResult> results = new List<ValidationResult>(((IValidatableObject)ose.Entity).Validate(null));
if (results.Count > 0)
throw new CustomException(results);
}
}

最佳答案

仅当您使用 DbContext API 而不是 ObjectContext API 时才会调用内置验证。

关于.net - EF SaveChanges 不调用 Validate (IValidatableObject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13073221/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com