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 を作成します。ほとんどの場合、すべてがうまく機能しますが、この 1 つのエラーが発生し続け、その理由を理解できないようです。

ここにエラーが発生するコードがあります

private List ParseAdicionalValues(XElement question, string entityNamespace, List adicionalValues, List existingValues) { existingValues = existingValues.Distinct().ToList(); if (!adicionalValues.Any()) return existingValues;

    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