0

これは本当に私を困惑させました。データベースに 4 つのテーブルがありますが、残念ながら、このテーブルを設計した人は参照制約を作成していません。そのため、利用可能なナビゲーション プロパティはありません。

4 つのテーブルは次のとおりです。

CiscoPhoneReport
ApplicationSummary
CSQActivityReport
CallDistributionSummary

PhoneReportIDこれは、CiscoPhoneReport のそれぞれに 1 ApplicationSummary、3 CSQActivityReport、および 3があるという考え方ですCallDistributionSummary

以下のような JSON 形式の出力が必要です。

`[{
   "appSummary":{
   "startDate":"2015-09-01T00:00:00",
   "endDate":"2015-09-30T00:00:00",
   "applicationName":"RationalDrugTherapy",
   "callsPresented":14504,
   "callsAbandoned":1992,
   "callsHandled":12512
  },
  "csqModel":[
   {
     "startDate":null,
     "csqid":"3",
     "callsPresented":6271,
     "avgQueueTime":"00:00:21",
     "callsHandled":0,
     "avgAnswerSpeed":"00:00:00",
     "avgHandleTime":"00:02:08",
     "callsHandledGreaterThan3t":5742,
     "callsAbandoned":99,
     "avgAbandonTime":"00:02:20",
     "maxQueueTime":"00:25:26",
     "maxHandleTime":"00:19:33",
     "maxAbandonTime":"00:17:50"
   },{
     "startDate":null,
     "csqid":"3",
     "callsPresented":6271,
     "avgQueueTime":"00:00:21",
     "callsHandled":0,
     "avgAnswerSpeed":"00:00:00",
     "avgHandleTime":"00:02:08",
     "callsHandledGreaterThan3t":1728,
     "callsAbandoned":99,
     "avgAbandonTime":"00:02:20",
     "maxQueueTime":"00:25:26",
     "maxHandleTime":"00:19:33",
     "maxAbandonTime":"00:17:50"
  }, {
    "startDate":null,
    "csqid":"3",
    "callsPresented":6271,
    "avgQueueTime":"00:00:21",
    "callsHandled":0,
    "avgAnswerSpeed":"00:00:00",
    "avgHandleTime":"00:02:08",
    "callsHandledGreaterThan3t":3363,
    "callsAbandoned":99,
    "avgAbandonTime":"00:02:20",
    "maxQueueTime":"00:25:26",
    "maxHandleTime":"00:19:33",
    "maxAbandonTime":"00:17:50"
  }]
}]`

このために、DTO を作成しました。

`public class AppSummary
 {
   public string PhoneReportID { get; set; }
   public DateTime StartDate { get; set; }
   public DateTime EndDate { get; set; }
   public string ApplicationName { get; set; }
   public int CallsPresented { get; set; }
   public int CallsAbandoned { get; set; }
   public int CallsHandled { get; set; }
 }
`

`public class CSQModel
    {
        public string StartDate { get; set; }
        public string CSQID { get; set; }
        public int CallsPresented { get; set; }
        public TimeSpan AvgQueueTime { get; set; }
        public int CallsHandled { get; set; }
        public TimeSpan AvgAnswerSpeed { get; set; }
        public TimeSpan AvgHandleTime { get; set; }
        public int CallsHandledGreaterThan3t { get; set; }
        public int CallsAbandoned { get; set; }
        public TimeSpan AvgAbandonTime { get; set; }
        public TimeSpan MaxQueueTime { get; set; }
        public TimeSpan MaxHandleTime { get; set; }
        public TimeSpan MaxAbandonTime { get; set; }      
    }
`

`public class PhoneReport
    {
        public AppSummary AppSummary { get; set; }
        //Initially, I had it like this
        public CSQModel CSQModel { get; set; }

        //I renamed the property as LIST to see if I could use it and add data to the list in linq, but I couldn't use the list within select expression in linq.
        //public List<CSQModel> CSQModel { get; set; }

    }
`

CSQModel クラスには、CSQActivityReportCallDistributionSummaryテーブルの両方からのデータが必要です。

以下のように、テーブル結合を含む linq ステートメントを作成できました。

var res = from cpr in db.CiscoPhoneReport 
        join app in db.ApplicationSummary on cpr.PhoneReportID equals          app.PhoneReportID into g1
        from appGroup in g1.DefaultIfEmpty()
        join csq in db.CSQActivityReport on cpr.PhoneReportID equals csq.PhoneReportID into g2
        from csqGroup in g2.DefaultIfEmpty()
        join call in db.CallDistributionSummary on cpr.PhoneReportID equals call.PhoneReportID into g3
        from callGroup in g3.DefaultIfEmpty()
        where cpr.PhoneReportID == phoneReportID
        select new PhoneReport
        {
           AppSummary = new AppSummary
          {
             StartDate = cpr.StartDate,
             EndDate = cpr.EndDate,
             ApplicationName = appGroup.ApplicationName,
             CallsPresented = appGroup.CallsPresented,
             CallsAbandoned = appGroup.CallsAbandoned,
             CallsHandled = appGroup.CallsHandled

         },
         CSQModel = new CSQModel
         {
             CSQID = csqGroup.CSQID.ToString(),
             CallsPresented = csqGroup.CallsPresented,
             AvgQueueTime = csqGroup.AvgQueueTime,                                                
             AvgHandleTime = csqGroup.AvgHandleTime, 
             CallsHandledGreaterThan3t = callGroup.CallsHandledGreaterThan3t, 
             CallsAbandoned = csqGroup.CallsAbandoned,
             AvgAbandonTime = csqGroup.AvgAbandonTime,
             MaxQueueTime = csqGroup.MaxQueueTime,
             MaxHandleTime = csqGroup.MaxHandleTime,
             MaxAbandonTime = csqGroup.MaxAbandonTime
         }
   };
`

私が得ている結果は、SQL の内部結合のように、9 行のデータのセットです。しかし、これは私が望んでいたものではありません。

上記の JSON 形式のデータを取得するにはどうすればよいですか? 私はそれをまったく理解できませんでした。

4

3 に答える 3

0

マスター レコードごとに、2 つの別個の子テーブルにそれぞれ 3 つのレコードがあります。何らかの結合を行うと、さらに情報を追加しない限り、(直接 T-SQL を使用した場合でも) 9 つのレコードが得られます。

SQL でこれを行う 1 つの方法は、テーブル A のレコード 1 をテーブル B のレコード 1 に結合することです。これを行うには、インデクサーが必要です。T-SQL の 1 つのオプションはROW_NUMBER()、各子テーブルで関数を使用し、その値を結合で使用することです。ただし、ROW_NUMBER()LINQ には拡張されていません。

重複したレコードを取得することに耐えられず、Distinct()子の結果セットごとに呼び出しを行うだけです。次に、これを 2 つまたは 3 つの個別のクエリとして実行できます。

注: これをストアド プロシージャの 3 つの結果セットにバンドルできます。EntityFramework を簡単に取得して、各結果を POCO に逆シリアル化できます。

            var objCtx = ((IObjectContextAdapter)ctx).ObjectContext;

            using (SqlCommand cmd = ctx.Database.Connection.CreateCommand() as SqlCommand)
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "<your proc here>";

                var param = cmd.CreateParameter();
                param.ParameterName = "@param1";
                param.Value = someValue;
                cmd.Parameters.Add(param);

                await cmd.Connection.OpenAsync();
                using (var reader = await cmd.ExecuteReaderAsync())
                {
                    var results = objCtx.Translate<type1Here>(reader).ToList();
                    reader.NextResult();
                    var results2 = objCtx.Translate<type2Here>(reader).ToList();
                    reader.NextResult();
                    var results3 = objCtx.Translate<type3Here>(reader).ToList();
                    reader.NextResult();
                }
            }
于 2015-10-21T22:10:39.717 に答える
-1

オブジェクトをシリアライズできます:

            DataContractJsonSerializer serializer = new DataContractJsonSerializer(GenericObject.GetType());

            MemoryStream ms = new MemoryStream();
            serializer.WriteObject(ms, GenericObject);
            string json = Encoding.UTF8.GetString(ms.ToArray());
            ms.Close();
            return json;
于 2015-10-21T22:26:00.723 に答える