我遇到这种情况:
private static EntityBuilderCore entityBuilderCore = ServiceFactory.Create<EntityBuilderCore>();
private List<Set> SplitBySetId(List<Step> stepList)
{
List<Set> outputSetList = new List<Set>();
using (entityBuilderCore)
{
stepList.ForEach(step =>
{
// For each step, I find the corrispectives set's ids (one or more).
// Then, I create the Set
List<int> setIdList = entityBuilderCore.GetSetIdByStep(step);
// Create Sets and adding to the output list
setIdList.ToList().ForEach(id =>
{
if (!outputSetList.Any(set => set.Id == id))
outputSetList.Add((Set)entityBuilderCore.GetEntity(typeof(Set), id));
});
});
}
return outputSetList;
}
但我可以在很多Set中细分很多步骤......所以我想以这种方式进行并行化(看起来是添加部分):
private List<Set> SplitBySetId(List<Step> stepList)
{
List<Set> outputSetList = new List<Set>();
using (entityBuilderCore)
{
stepList.ForEach(step =>
{
// For each step, I find the corrispectives set's ids (one or more).
// Then, I create the Set
List<int> setIdList = entityBuilderCore.GetSetIdByStep(step);
// Create Sets and adding to the output list
var tempList = setIdList.Distinct()
.AsParallel()
.Where(id => !outputSetList.Any(set => set.Id == id))
.Select(setId => (Set)entityBuilderCore.GetEntity(typeof(Set), setId));
outputSetList.AddRange(tempList);
});
}
return outputSetList;
}
但我不确定entityBuilderCore的线程安全性。核心是:
class EntityBuilderCore : CoreBase
{
private static EntityRepository Repository;
protected override string _connectionString
{
get { return ConfigurationService.Instance.GetValue("connessione_database_sinistriweb"); }
}
private EntityBuilderCore()
{
Repository = new EntityRepository() { ConnectionString = _connectionString };
}
public BaseEntity GetEntity(Type entityType, int id)
{
return EntityBuilder.BuildEntity(entityType, Repository.GetEntity(entityType, id));
}
// ...
public List<int> GetSetIdByStep(Step step)
{
return Repository.GetSetIdByStep(step);
}
}
class EntityRepository : RepositoryBase
{
Dictionary<Type, string> tableDictionary = new Dictionary<Type, string>();
public EntityRepository()
{
tableDictionary.Add(typeof(SQL), "PROCESSI.DBO.GFE_SQL");
tableDictionary.Add(typeof(Step), "PROCESSI.DBO.GFE_STEP");
tableDictionary.Add(typeof(StepSet), "PROCESSI.DBO.GFE_SET");
}
public DataRow GetEntity(Type systemType, int id)
{
string entityTable;
tableDictionary.TryGetValue(systemType, out entityTable);
using (SqlConnection connection = new SqlConnection(ConnectionString))
using (SqlCommand command = new SqlCommand(string.Format("SELECT * FROM {0} WHERE ID = @ID", entityTable), connection))
{
connection.Open();
command.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = id;
using (SqlDataReader dr = command.ExecuteReader())
{
if (dr.Read())
{
DataTable entityDataTable = new DataTable();
SqlDataAdapter dataAdapter = new SqlDataAdapter();
dataAdapter.SelectCommand = command;
connection.Close();
dataAdapter.Fill(entityDataTable);
return entityDataTable.Rows[0];
}
}
}
return null;
}
public List<int> GetSetIdByStep(Step step)
{
// bla bla
}
// ...
}
我更喜欢在EntityBuilder类中只使用一个entityBuilderCore。我更喜欢不每次实例化entityBuilderCore,我认为是没用的。但我担心不是线程安全,因为SplitBySetId方法同时被许多任务使用
class EntityBuilder
{
public static BaseEntity BuildEntity(Type entityType, DataRow dr)
{
if (entityType == typeof(SQL))
return BuildSQL(dr);
if (entityType == typeof(Step))
return BuildStep(dr);
if (entityType == typeof(Set))
return BuildSet(dr);
return null;
}
//...
private static Step BuildStep(DataRow dr)
{
using (EntityBuilderCore entityBuilderCore = ServiceFactory.Create<EntityBuilderCore>())
{
Step s = new Step()
{
Id = Convert.ToInt16(dr["ID"]),
//... bla bla
};
return s;
}
}
private static Set BuildSet(DataRow dr)
{
using (EntityBuilderCore entityBuilderCore = ServiceFactory.Create<EntityBuilderCore>())
{
Set s = new Set()
{
Id = Convert.ToInt16(dr["ID"]),
//...
};
return s;
}
}
}