シードファイルからユーザーオブジェクトの「場所」データをシードしたい
C#オブジェクト。PointはNetTopologySuite.Geometries.Point
はユーザーオブジェクトの一部です
public class User: IdentityUser<int> {
// member data here
public Point Location { get; set; } // has lat/lng data points
}
このようなことをして、起動時にデータベースにデータをシードします
public void SeedUsers()
{
if (!_userManager.Users.Any())
{
var userData = System.IO.File.ReadAllText("Data/UserSeedData.json");
var users = JsonConvert.DeserializeObject<List<User>>(userData);
var roles = new List<Role>
{
new Role{Name = "Member"},
new Role{Name = "Admin"},
new Role{Name = "Moderator"},
new Role{Name = "VIP"},
};
foreach (var role in roles)
{
_roleManager.CreateAsync(role).Wait();
}
foreach (var user in users)
{
user.Photos.SingleOrDefault().IsApproved = true;
_userManager.CreateAsync(user, "password").Wait();
_userManager.AddToRoleAsync(user, "Member").Wait();
}
}
}
このようなjson配列のjsonファイル "UserSeedData.json"を使用して、lng/latデータポイントを表すある種の「位置」データをそこに貼り付けることができます。
{
"Email": "[email protected]",
"Username": "Lola",
"Gender": "female",
"DateOfBirth": "1994-02-21",
"Password": "password",
"Created": "2017-08-02",
"LastActive": "2017-08-02",
"Introduction": "blah blah blah",
"LookingFor": "blah blah blah",
"City": "San Francisco",
"Country": "United States",
"Longitude": -122.431297,
"Latitude": 37.773972,
"Location": // something here!!!
"Photos": [{
"url": "https://randomuser.me/api/portraits/women/3.jpg",
"isMain": true,
"description": "Non deserunt labore sunt ex laboris et adipisicing ullamco officia minim."
}]
}
これで、シードメソッドでこのようなことができることがわかりましたが、.jsonファイルに含める方法を探しているので、さまざまなデータポイントを使用できます
foreach (var user in users)
{
user.Photos.SingleOrDefault().IsApproved = true;
user.Location = new Point(-122.4194155, 37.7749295) { SRID = 4326 };
_userManager.CreateAsync(user, "password").Wait();
_userManager.AddToRoleAsync(user, "Member").Wait();
}
NetTopologiySuiteのPointオブジェクトにはパラメーターのないコンストラクターが含まれていないため、逆シリアル化中にJSONを簡単にマップすることはできません。
ただし、独自のLocationオブジェクトを簡単に作成し、ループ内で値をNetTopologySuiteのPointオブジェクトにマッピングすることができます。
まず、新しいLocationオブジェクトを定義します...
public class Location
{
public double Longitude { get; set; }
public double Latitude { get; set; }
public int SRID { get; set; }
}
次に、JSONのロケーション行を以下の行で更新して、ロケーションオブジェクトを定義します。
"Location": {"Longitude":-122.4194155, "Latitude":37.7749295, "SRID":4326},
完全なJSON:
[{
"Email": "[email protected]",
"Username": "Lola",
"Gender": "female",
"DateOfBirth": "1994-02-21",
"Password": "password",
"Created": "2017-08-02",
"LastActive": "2017-08-02",
"Introduction": "blah blah blah",
"LookingFor": "blah blah blah",
"City": "San Francisco",
"Country": "United States",
"Longitude": -122.431297,
"Latitude": 37.773972,
"Location": {"Longitude":-122.4194155, "Latitude":37.7749295, "SRID":4326},
"Photos": [{
"url": "https://randomuser.me/api/portraits/women/3.jpg",
"isMain": true,
"description": "Non deserunt labore sunt ex laboris et adipisicing ullamco officia minim."
}]
}]
次に、新しいLocationオブジェクトを使用するようにUserオブジェクトを更新し、NetTopologySuiteのPointオブジェクトにJsonIgnore属性を設定します。
public class User : IdentityUser<int>
{
// member data here
public Location Location { get; set; }
[JsonIgnore]
public Point LocationPoint { get; set; } // has lat/lng data points
}
最後に、foreachループを更新してデータをマップします...
foreach (var user in users)
{
user.Photos.SingleOrDefault().IsApproved = true;
user.LocationPoint = new Point(user.Location.Longitude, user.Location.Latitude) {SRID = user.Location.SRID};
_userManager.CreateAsync(user, "password").Wait();
_userManager.AddToRoleAsync(user, "Member").Wait();
}
以上のように、NetTopologySuiteのPointオブジェクトをユーザーオブジェクト内で直接使用することを再考し、代わりに独自のロケーションオブジェクトを使用することをお勧めします。次に、実際にPointを使用するコードに近いNetTopologySuiteのPointオブジェクトに転置します。ただし、これはアプリケーションによって異なります。
パーティーには少し遅れますが、これは私の見解です。Point
を現在のJsonシリアライザーの設定と簡単に互換させることができます。
[DataContract]
public class GeoLocation : NetTopologySuite.Geometries.Point
{
const int GoogleMapSRID = 4326 ;
public GeoLocation(double latitude, double longitude)
: base(x: longitude, y: latitude) =>
base.SRID = GoogleMapsSRID;
[DataMember]
public double Longitude => base.X;
[DataMember]
public double Latitude => base.Y;
}
DataContract
とDataMember
はここで重要です:
new GeoLocation(42.9074, -78.7911).ToJson() => {"longitude":42.9074,"latitude":-78.7911}