我遇到的情况是我们的系统中存在伪造数据的电话号码,并且不想让新的虚假价值出现。但是数据库中的错误数据现在需要保留到编辑之前。 (有些客户[痛苦地]使用电话号码链接到某些第三方集成作为关键值,所以即使虚假数字也很有用。我不能 - 但是 - 只是将它们炸掉。)
所以我想在我的Phone
NHibernate实体的MyEntity
setter中添加QA,以阻止虚假值,除非该值与当前的值相同数据库。
我的问题似乎是NHibernate(give或take)通过其null构造函数创建MyEntity
的每个实例,然后通过更改其属性的值来对其进行水合。 也就是说,在初始水合期间,调用Phone
属性的setter。因此,如果我在setter中有值QA,它会在水化过程中被调用,之后我会有“原始值”在实体中进行检查。所以我需要访问db。
如果我试图通过设置另一个存储库并抓住同一个实体来“回到”数据库中,我现在正在补充,Phone
中没有任何内容,尽管链接表中的所有内容都在实体上
如果我正处于NHibernate水合作用的中间而非系统启动的编辑(“系统”,那么在setter 中知道的方法同样有用“启动”意味着,例如,Flynn(用户)进行了一些编辑,系统保存了它们。然后我就跳过验证了。
看,实际代码。我在MyEntity上放了一个static
bool
,告诉我什么时候回来让thisEntity
无需支票即可保湿。
set
{
string valueToEvaluate = value;
if (null != valueToEvaluate)
{
Regex nonNumericCharacters = new Regex(@"[^0-9]");
valueToEvaluate = nonNumericCharacters.Replace(valueToEvaluate, string.Empty);
if (10 != valueToEvaluate.Length && !valueToEvaluate.Equals(string.Empty))
{
if (MyEntity.ReachingBack) // let it reach back to get current value without QA.
{
valueToEvaluate = value;
}
else
{
MyEntity.ReachingBack = true; // avoid recursive bogus value hell.
IMyEntityRepository entityRepo = ServiceLocator.Current.GetInstance<IMyEntityRepository>();
MyEntity thisEntity = entityRepo.GetById(this.Id); // luckily already hydrated.
MyEntity.ReachingBack = false; // stop avoiding recursive bogus value hell.
// !!!!: Unfortunately, all of the thisEntity values that aren't from linked tables
// are blank at this point. Phone most notably is blank.
if (null != thisEntity && thisEntity.Phone.Trim().Equals(value.Trim()))
{
valueToEvaluate = thisEntity.Phone; // no change. not even dash and paren cleanup.
}
else
{
throw new Exception("Invalid Phone Number");
}
}
}
}
_phone = valueToEvaluate;
}
我还尝试使用GetById
上的新方法替换IMyEntityRepository
代码,以使用QueryOver计算与我正在检查的条目具有相同Phone
的条目数,并收到A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance:...
HibernateException。我想我需要第二次会议来解决这个问题? /混淆
编辑:此代码添加到MyEntityRepository
时出现相同的级联错误:
public int GetCountWithSpecificPhone(string strPhone)
{
var sql = "select Id from Entity where Phone = '" + strPhone + "'";
IQuery query = GetSession().CreateSQLQuery(sql);
IList<MyEntity> spam = query.List<MyEntity>();
return spam.Count;
}
我必须能够在数据库中使用sproc或其他后门,对吗?
与this并不完全不同,但我希望在实体上进行验证,而不是在编辑时进行验证。