この質問はすでに見ましたが、実際に何が起こっているのかを理解できるように説明していません。私は何年も開発してきましたが、これまでにこれに遭遇したことはありません (ただし、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; }
前もって感謝します。