我已经看过这个问题,但它没有解释它,所以我了解实际发生了什么。我已经开发了多年,以前从未遇到过这种情况(尽管我对 Linq 和 Parallel 的使用是最近才使用的)。
我的代码是:
Parallel.ForEach(databaseMetadata.Rows.Cast<DataRow>(), row => {
var fieldName = row.Item("Name", "");
var field = this.Fields.Where(f => f.Name.ToLower() == fieldName.ToLower()).SingleOrDefault();
if(field != null) { field.Validate(this, connection, row); }
});
在 field.Validate 函数中,它将字段对象上名为“HasBeenValidated”的属性设置为 true,但是,一旦我退出此 Parallel.ForEach 循环,该属性就会设置回 false。有人可以解释为什么会发生这种情况以及我可以做些什么来确保循环内的更改在循环外持续存在。
编辑:
下面是 field.Validate 中的代码副本:
internal void Validate(EntityAttribute entity, SqlConnection connection, [AllowNull] DataRow metadata) {
this.HasBeenValidated = true;
var isRequired = this.IsRequired;
var maxLength = this.MaxLength;
var isAutoGenerated = this.IsAutoGenerated;
var dataType = this.member.PropertyType;
var dataTypeAsString = "";
if(metadata != null) {
isRequired = metadata.Item("IsRequired", false);
maxLength = metadata.Item("MaxLength", 0);
isAutoGenerated = metadata.Item("IsAutoGenerated", false);
dataTypeAsString = metadata.Item("DataType", "");
if(dataTypeAsString == this.member.PropertyType.ToSqlServerDataType()) { dataTypeAsString = ""; }
} else {
dataTypeAsString = this.member.PropertyType.ToSqlServerDataType();
}
if(metadata == null || isRequired != this.IsRequired || maxLength != this.MaxLength || isAutoGenerated != this.IsAutoGenerated || dataTypeAsString != "") {
var sql = string.Format((metadata == null ? "ALTER TABLE [{0}].[{1}] ADD" : "ALTER TABLE {0} ALTER COLUMN"), entity.Schema, entity.Name) + " " + this.Sql + ";";
if(!connection.ExecuteCommand(sql, 1)) {
throw new InvalidOperationException("Unable to create or alter column '" + this.Name + "' on table '" + entity.Name + "'.");
}
}
}
HasBeenValidated 属性在字段对象上定义为:
internal bool HasBeenValidated { get; set; }
提前致谢。