I have a JSON value stored in SQL Server. I want to retrieve that JSON value and bind it to C# property (which is deserialized to desired entity). I want to know what would be the best practice to do that effectively? Right now, I'm doing like this:
Public class Employee
{
public int Id;
public string Name;
public int Age;
}
Public class EmployeeData
{
public string JsonEmployeeText {get;set;} // Binding the json string from database
public List<Employee> Employees { get { return JsonConvert.DeserializeObject<Employee>(JsonEmployeeText );}} //Converting the retrieved json string from Database to c# entity
}
I guess we should not do any sort of database logic on getters as it can sometimes delay the process of initialization in case we need to use this we need to make sure we enable the lazy loading
Imagine we have a number of related objects (equivalently DB tables), for example:
public class Person {
private String name;
private Date birthday;
private int height;
private Job job;
private House house;
..
}
public class Job {
private String company;
private int salary;
..
}
public class House {
private Address address;
private int age;
private int numRooms;
..
}
public class Address {
private String town;
private String street;
..
}
How to best design a system for easily defining and accessing widely varying subsets of data on these objects/tables? Design patterns, pros and cons, are very welcome. I'm using Java, but this is a more general problem.
For example, I want to easily say:
I'd like some object with (Person.name, Person.height, Job.company, Address.street)
I'd like some object with (Job.company, House.numRooms, Address.town)
Etc.
Other assumptions:
We can assume that we're always getting a known structure of objects on the input, e.g. a Person with its Job, House, and Address.
The resulting object doesn't necessarily need to know the names of the fields it was constructed from, i.e. for subset defined as (Person.name, Person.height, Job.company, Address.street) it can be the array of Objects {"Joe Doe", 180, "ACompany Inc.", "Main Street"}.
The object/table hierarchy is complex, so there are hundreds of data fields.
There may be hundreds of subsets that need to be defined.
A minority of fields to obtain may be computed from actual fields, e.g. I may want to get a person's age, computed as (now().getYear() - Person.birtday.getYear()).
Here are some options I see:
A SQL view for each subset.
Minuses:
They will be almost the same for similar subsets. This is OK just for field names, but not great for the joins part, which could ideally be refactored out to a common place.
Less testable than a solution in code.
Using a DTO assembler, e.g. http://www.genericdtoassembler.org/
This could be used to flatten the complex structure of input objects into a single DTO.
Minuses:
I'm not sure how I'd then proceed to easily define subsets of fields on this DTO. Perhaps if I could somehow set the ones irrelevant to the current subset to null? Not sure how.
Not sure if I can do computed fields easily in this way.
A custom mapper I came up with.
Relevant code:
// The enum has a value for each field in the Person objects hierarchy
// that we may be interested in.
public enum DataField {
PERSON_NAME(new PersonNameExtractor()),
..
PERSON_AGE(new PersonAgeExtractor()),
..
COMPANY(new CompanyExtractor()),
..
}
// This is the container for field-value pairs from a given instance of
// the object hierarchy.
public class Vector {
private Map<DataField, Object> fields;
..
}
// Extractors know how to get the value for a given DataField
// from the object hierarchy. There's one extractor per each field.
public interface Extractor<T> {
public T extract(Person person);
}
public class PersonNameExtractor implements Extractor<String> {
public String extract(Person person) {
return person.getName();
}
}
public class PersonAgeExtractor implements Extractor<Integer> {
public int extract(Person person) {
return now().getYear() - person.getBirthday().getYear();
}
}
public class CompanyExtractor implements Extractor<String> {
public String extract(Person person) {
return person.getJob().getCompany();
}
}
// Building the Vector using all the fields from the DataField enum
// and the extractors.
public class FullVectorBuilder {
public Vector buildVector(Person person) {
Vector vector = new Vector();
for (DataField field : DataField.values()) {
vector.addField(field, field.getExtractor().extract(person));
}
return vector;
}
}
// Definition of a subset of fields on the Vector.
public interface Selector {
public List<DataField> getFields();
}
public class SampleSubsetSelector implements Selector {
private List<DataField> fields = ImmutableList.of(PERSON_NAME, COMPANY);
...
}
// Finally, a builder for the subset Vector, choosing only
// fields pointed to by the selector.
public class SubsetVectorBuilder {
public Vector buildSubsetVector(Vector fullVector, Selector selector) {
Vector subsetVector = new Vector();
for (DataField field : selector.getFields()) {
subsetVector.addField(field, fullVector.getValue(field));
}
return subsetVector;
}
}
Minuses:
Need to create a tiny Extractor class for each of hundreds of data fields.
This is a custom solution that I came up with, seems to work and I like it, but I feel this problem must have been encountered and solved before, likely in a better way.. Has it?
Edit
Each object knows how to turn itself into a Map of fields, keyed on an enum of all fields.
E.g.
public enum DataField {
PERSON_NAME,
..
PERSON_AGE,
..
COMPANY,
..
}
public class Person {
private String name;
private Date birthday;
private int height;
private Job job;
private House house;
..
public Map<DataField, Object> toMap() {
return ImmutableMap
.add(DataField.PERSON_NAME, name)
.add(DataField.BIRTHDAY, birthday)
.add(DataField.HEIGHT, height)
.add(DataField.AGE, now().getYear() - birthday.getYear())
.build();
}
}
Then, I could build a Vector combining all the Maps, and select subsets from it like in 3.
Minuses:
Enum name clashes, e.g. if Job has an Address and House has an Address, then I want to be able to specify a subset taking street name of both. But how do I then define the toMap() method in the Address class?
No obvious place to put code doing computed fields requiring data from more than one object, e.g. physical distance from Address of House to Address of Company.
Many thanks!
Over in-memory object mapping in the application, I would favor database processing of the data for better performance. Views, or more elaborate OLAP/datawarehouse tooling could do the trick. If the calculated fields remain basic, as in "age = now - birth", I see nothing wrong with having that logic in the DB.
On the code side, given the large number of DTOs you have to deal with, you could use classless dynamic (available in some JVM languages) or JSON objects. The idea is that when a data structure changes, you only need to modify the DB and the UI, saving you the cost of changing a whole bunch of classes in between.
I have at least two different classes like following :
//NOTE : these two classes have getter and setter also
class Artist {
String artistName;
String artistWebsite;
String artistDbpedia;
String artistImage;
List<String> astistAlbumsName;
List<String> astistAlbumsUrl;
}
class Venu {
String VenuName;
String VenuWebsite;
String VenuDbpdia;
String VenuImage;
String VenuDescription;
List<String> venuFans;
}
I want to have a producer class to get an xml file as an input and detect the type of xml (venu/artist) then start to create a product object based on the input.
the problem :
I want to create an interface for aggregate the similarity between above two classes so my interface would be:
interface Model {
public String getImage();
public String getName();
public String getWebsite();
public String getdbpedia();
}
Then I can implement this interface in my builder class and above two classes but how about those different methods?
such as getVenuFans / getArtistAlbumName / etc....?
How can I call them from my producer?
this is my builder :
Class Builder implements Model {
public String getImage(){}
public String getName(){}
public String getWebsite(){}
public String getdbpedia(){}
}
and this can be my producer :
Class Producer {
public Producer()
{
Builder b = null;
//assume Venu and Artist implements Model
b = (Builder) new Venu();
//I don't have access to getVenuFans()!
b = (Builder) new Artist();
//I don't have access to getArtistAlbumsName() / etc...
}
}
You don't have access to those methods because you're casting the objects to a Builder, and Builder doesn't have those methods.
I see what you're trying to do, but I don't think it will work. For example, getVenueFans (I'm assuming you mean venue) is only appropriate for the Venue class. It doesn't make sense to try and abstract that into an interface that other non-Venue classes will implement.
I think what you have is good: You've abstracted the common methods into an interface. To call the methods on Venue and Artist, the consuming code will need to cast the objects to the appropriate type, then call the methods on it. And that's not as bad as you might think. It's the consuming code that knows what type it's dealing with (otherwise, why would it be trying to call getVenueFans?), so that's the point where it makes sense to cast and call the method directly.
While viewing Evans' project on sample DDD project, I notice that in the Cargo entity, Evans uses tracknumber which is an value object. Why he didn't chooses plain string tracknumber instead chooses value object for identity? Here is snippet from Evans:
public class Cargo implements Entity<Cargo> {
private TrackingId trackingId
}
public final class TrackingId implements ValueObject<TrackingId> {
private String id;
/**
* Constructor.
*
* #param id Id string.
*/
public TrackingId(final String id) {
Validate.notNull(id);
this.id = id;
}
A couple of things that would achieve:
Encapsulates the logic that the Tracking ID should not be null
Encapsulates the logic that the Tracking ID should not change once set.
With a plain string, the Cargo object would have to be aware of these rules. Using the Value Object approach means the TrackingId maintains these rules about itself.
Hi all I have a horrid database I gotta work with and linq to sql is the option im taking to retrieve data from. anywho im trying to reuse a function by throwing in a different table name based on a user selection and there is no way to my knowledge to modify the TEntity or Table<> in a DataContext Query.
This is my current code.
public void GetRecordsByTableName(string table_name){
string sql = "Select * from " + table_name;
var records = dataContext.ExecuteQuery</*Suppossed Table Name*/>(sql);
ViewData["recordsByTableName"] = records.ToList();
}
I want to populate my ViewData with Enumerable records.
You can call the ExecuteQuery method on the DataContext instance. You will want to call the overload that takes a Type instance, outlined here:
http://msdn.microsoft.com/en-us/library/bb534292.aspx
Assuming that you have a type that is attributed correctly for the table, passing that Type instance for that type and the SQL will give you what you want.
As casperOne already answered, you can use ExecuteQuery method first overload (the one that asks for a Type parameter). Since i had a similar issue and you asked an example, here is one:
public IEnumerable<YourType> RetrieveData(string tableName, string name)
{
string sql = string.Format("Select * FROM {0} where Name = '{1}'", tableName, name);
var result = YourDataContext.ExecuteQuery(typeof(YourType), sql);
return result;
}
Pay attention to YourType since you will have to define a type that has a constructor (it can't be abstract or interface). I'd suggest you create a custom type that has exactly the same attributes that your SQL Table. If you do that, the ExecuteQuery method will automatically 'inject' the values from your table to your custom type. Like that:
//This is a hypothetical table mapped from LINQ DBML
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.ClientData")]
public partial class ClientData : INotifyPropertyChanging, INotifyPropertyChanged
{
private int _ID;
private string _NAME;
private string _AGE;
}
//This would be your custom type that emulates your ClientData table
public class ClientDataCustomType
{
private int _ID;
private string _NAME;
private string _AGE;
}
So, on the former example, the ExecuteQuery method would be:
var result = YourDataContext.ExecuteQuery(typeof(ClientDataCustomType), sql);