ContainerID
(整数)、 ContainerNumber
(文字列)、 Title
(文字列)、 Date
(日付)の4つのプロパティを持つエンティティContainer
とします。
私は、 CustomFieldID
(整数)、 ContainerID
(整数および外部キー)、 FieldName
(文字列)、 FieldContent
(文字列)の3つのプロパティを持つContainerCustomFields
という2番目のエンティティを持ってCustomFieldID
。 ContainerCustomFields
のための実体を格納し、ユーザー定義のカスタムフィールドContainer
エンティティ。データは次のようになります。
コンテナの場合:
Container
---------
ID | Number | Title | Date |
=====================================================
1 | 10000 | 1st Title | 1/12/2017 |
2 | 10543 | 2nd Title | 1/31/2017 |
3 | 10667 | 3rd Title | 4/12/2016 |
4 | 12889 | 4th Title | 5/23/2012 |
カスタムフィールドの場合:
ID | ContainerID | FieldName | Content |
=====================================================
1 | 1 | Colour | Blue |
2 | 1 | Height | 5000 |
3 | 1 | Length | 9100 |
4 | 4 | Colour | Gray |
次のようにデータを返すことは可能ですか?
Container
---------
ID | Number | Title | Date | Colour | Height | Length |
====================================================================================
1 | 10000 | 1st Title | 1/12/2017 | Blue | 5000 | 9100 |
2 | 10543 | 2nd Title | 1/31/2017 | | | |
3 | 10667 | 3rd Title | 4/12/2016 | | | |
4 | 12889 | 4th Title | 5/23/2012 | Gray | | |
各コンテナのカスタムフィールドとその値のリストを取得し、selectステートメントを使用してエンティティから必要な列を選択できます。これらの2つのステートメントを組み合わせるにはどうすればよいですか?
For Each customField In _db.ContainerCustomFields
.Where(Function(cf) cf.ContainerID = newBox.ContainerID)
returnContainers.Select(Function(c) New With
{.ContainerID = c.ContainerID,
.Number = c.ContainerNumber,
.Title = c.Title,
.Date = c.Date })
私はWeb API 2を使用して、これをWebアプリケーションの匿名タイプとして返します。
最初に各コンテナにグループ化し、フィールドと値をgrps内の配列に変換します。
var grps = from c in _db.Containers
join ccf in _db.ContainerCustomFields
on c.ContainerID equals ccf.ContainerID
select new
{ContainerId = c.ContainerID,
ContainerNumber= c.ContainerNumber,
Title = c.Title,
Date = c.Date,
FieldName = ccf.FieldName,
FieldContent = ccf.FieldContent}
into f
group f by f.ContainerId
into myGroup
select new
{
ContainerId = myGroup.Key,
ContainerNumber = myGroup.Max(d => d.ContainerNumber),
Title = myGroup.Max(d => d.Title),
Date = myGroup.Max(d => d.Date),
Fields = myGroup.Select(d => d.FieldName).ToArray(),
Values = myGroup.Select(d => d.FieldContent).ToArray()
};
表示されるすべてのフィールド名を見つけます。
var fields = from ccf in _db.ContainerCustomFields
group ccf by ccf.FieldName
into grp
select grp.Key;
次に、コンテナーの列とすべての可能なフィールドを含むデータテーブルを作成します。
DataTable dt = new DataTable();
dt.Columns.Add("ContainerId", typeof(Int32));
dt.Columns.Add("ContainerNumber", typeof(String));
dt.Columns.Add("Title", typeof(String));
dt.Columns.Add("Date", typeof(DateTime));
foreach(var fld in fields)
{
dt.Columns.Add(fld, typeof(String));
}
次に、データのグループごとに、データテーブルの行を追加し、関連する各フィールドに値を追加します。
foreach (var row in grps)
{
DataRow dr = dt.NewRow();
dr["ContainerId"] = row.ContainerId;
dr["ContainerNumber"] = row.ContainerNumber;
dr["Title"] = row.Title;
dr["Date"] = row.Date;
for (int i = 0; i < row.Fields.Count(); i++)
{
dr[row.Fields[i]] = row.Values[i];
}
dt.Rows.Add(dr);
}
これで、データテーブルを使用してグリッドなどに入力できます。データテーブルの欠落しているフィールド値はnullに設定されます。
データベーステーブルに使用したセットアップコード:
CREATE TABLE Container
(
ContainerID Int,
ContainerNumber Varchar(50),
Title Varchar(50),
[Date] Date
)
INSERT INTO Container
VALUES
(1, '10000', '1st Title', '2017-01-12'),
(2, '10543', '2nd Title', '2017-01-31'),
(3, '10667', '3rd Title', '2017-04-12'),
(4, '12889', '4th Title', '2017-05-23')
CREATE TABLE ContainerCustomFields
(
CustomFieldID INT,
ContainerID Int,
FieldName Varchar(50),
FieldContent Varchar(50)
)
INSERT INTO ContainerCustomFields
VALUES
(1,1, 'Colour', 'Blue'),
(2,1, 'Height', '5000'),
(3,1, 'length', '9100'),
(4,4, 'Colour', 'Gray')