0

所以我使用LimeSurvey API将调查发送给用户,然后我有一个 XML 将告诉我如何解析它们并将我想要的信息插入到我的数据库中。下面的代码是我寻找仍然需要解析的用户,解析他们的响应然后插入数据库的地方。

using (SIREntities context = new SIREntities())
{
List<persons> personList = context.persons.Where(p => p.StateId == Survey.AfterAddParticipantStatusId).ToList();
personList = personList.Where(o => o.PersonId == 6795).ToList();
foreach (persons person in personList)
{
try
{
    personsurveys personSurvey = person.personsurveys.SingleOrDefault(s => s.surveyId == Survey.Surveyid);

    if (personSurvey == null)
        continue;

    Participant participant = Service.GetParticipantProperties(personSurvey.tokenId.Value);

    if (!participant.Completed.Equals("N"))
    {
        string responses = Service.GetResponsesByToken("json", personSurvey.token);
        SurveyParser<persons> parser = new SurveyParser<persons>(person, responses, Survey.Schema, Survey.Surveyid.ToString(), context);
        parser.Parse();

        if (Survey.AfterResponseStatusId.HasValue)
            NewStatus(person, Survey.AfterResponseStatusId.Value);

        byte[] allResponses = Service.GetResponsesByTokenPdf(personSurvey.token);
        if (allResponses.Length > 0)
            GetAllResponsesFile(person, allResponses);

        context.SaveChanges();

        personsToIndex.Add(person.PersonId);
    }
}
catch (Exception ex)
{
    UndoChangesEntity(context, person);
    LogHelper.Instance.Error(string.Format("Error parsing person {0} with error {1}", person.PersonId, ex.Message));
    LogHelper.Instance.Error("StackTrace: " + ex.StackTrace);
    if (ex.InnerException != null)
        LogHelper.Instance.Error("InnerException: " + ex.InnerException);
}
}
}

为了解析调查,我使用反射,因为我想解析不同的调查并且不想在每次有新调查时都编写代码。为此,我构建了一个 XML,它将告诉我如何匹配调查和数据库之间的信息。在大多数情况下,一切都很好,但我不断收到这个错误,似乎无法理解为什么。

这是发生错误的代码

private List ParseAdicionalValues(XElement question, string entityNamespace, List adicionalValues, List existingValues) { existingValues = existingValues.Distinct().ToList(); if (!adicionalValues.Any()) 返回现有值;

    List<string> addedValues = new List<string>();

    string fieldName = question.Element("namespace").Attribute("field") != null ? question.Element("namespace").Attribute("field").Value : string.Empty;
    string tableName = question.Element("namespace").Attribute("table") != null ? question.Element("namespace").Attribute("table").Value : string.Empty;
    string tableNamespace = question.Element("namespace").Attribute("tableNamespace") != null ?
        question.Element("namespace").Attribute("tableNamespace").Value : entityNamespace;

    if (string.IsNullOrEmpty(fieldName) || string.IsNullOrEmpty(tableName) || string.IsNullOrEmpty(tableNamespace))
        return existingValues;

    Type insertTpe = Type.GetType(tableNamespace);
    if (insertTpe == null)
        return existingValues;

    using (var context = new SIREntities())
    {
        var lookupEntity = context.Set(insertTpe);
        bool hasInserted = false;
        ArrayList newEntities = new ArrayList();
        foreach (var name in adicionalValues)
        {
            string query = "select * from " + tableName + " where " + fieldName + "=\"" + name.Trim() + "\"";
            var foundEntity = lookupEntity.SqlQuery(query).Cast<object>();
            if (foundEntity.Count() == 0)
            {
                hasInserted = true;
                object newEntity = Activator.CreateInstance(insertTpe);
                SetPropertyValue(newEntity, fieldName, name.Trim());
                lookupEntity.Add(newEntity);
                newEntities.Add(newEntity);
            }
            else
            {
                var castEntity = foundEntity.First();
                List<string> primaryKeys = GetEntityKeyNames(context, insertTpe);
                addedValues.Add(GetPropertyValue(castEntity, primaryKeys[0]));
            }
        }

        if (hasInserted)
            context.SaveChanges();

        foreach (var obj in newEntities)
        {
            List<string> primaryKeys = GetEntityKeyNames(context, insertTpe);
            string value = GetPropertyValue(obj, primaryKeys[0]);
            addedValues.Add(value);
        }
    }

    addedValues.AddRange(existingValues);
    addedValues = addedValues.Distinct().ToList();
    return addedValues;
}

代码所做的是检查信息是否已存在于数据库中(它是一个查找表),如果它不插入它。我收到错误的那一行是:

if (foundEntity.Count() == 0)

错误并不总是发生在相同的答案上。多次运行作业,错误发生在不同的答案上。我得到的错误如下:

2015-04-08 17:34:16.1177 - Unknown column 'Cisco Systems' in 'where clause'
2015-04-08 17:34:16.1187 - ERROR: StackTrace:    at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
   at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
   at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
   at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
   at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)
   at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__64()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__63()
   at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryReliably[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)
   at System.Data.Entity.Internal.Linq.InternalSet`1.<>c__DisplayClass11.<ExecuteSqlQuery>b__10()
   at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
   at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
   at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)
   at LimeSurvey.Utilities.SurveyParser`1.ParseAdicionalValues(XElement question, String entityNamespace, List`1 adicionalValues, List`1 existingValues) in XXX
   at LimeSurvey.Utilities.SurveyParser`1.MultipleChoice(Type entityType, XElement question, String questionId, String entityNamespace, String insertMode) in XXX
   at LimeSurvey.Utilities.SurveyParser`1.Parse() in XXX
   at LimeSurvey.Utilities.Surveys.GetResponses() in XXX
4

1 回答 1

0

问题是您在这里构建查询的方式:

string query = "select * from " + tableName + " where " + fieldName + "=\"" + name.Trim() + "\"";

尽管 MySQL 支持双引号中的字符串值,但最好使用单引号,因为您可能会产生意想不到的副作用。如果“名称”可能包含引号,您可能还需要在选择之前正确引用任何字段值。

于 2015-04-09T07:53:10.173 回答