serializing parent/child relationships with newtonsoft.json and linq to sql - linq-to-sql

I am having a problem. I have a table tblitems which has a primary key which has a child table tblweeks linked via foreign key. When using json.net to serialize json, even when the reference loop handling is set to referenceloophandling.ignore, it is serlilizing the parent tblitem class for every tblweekof linked to it. I don't want that but I still want some fields from the child class. Is there a way in my linq query to only select some columns from a child table or do I have to break the relationships? I'm confused, this seems like really unexpected behavior.
UPDATE
OK, I kind of have what I want now, I found I could use the select function on the child table to only select certain columns, but what is the best way to garentee the order of the child records? I want to make sure they are ordered by weekof in this example:
var q = from lineITem in db.tblBroadcastEntryItems
where lineITem.broadcastID == Int32.Parse(context.Request.QueryString[0])
select new
{
...,
week = lineITem.tblBroadcastEntryWeeks
.Select(c => new { c.weekof, c.spots, c.id })
};

Related

SQLAlchemy query all children's records of a parent

Imagine, I have this simple database model (Parent_id, Child_id are Foreing Keys)
Is there a way how to query straight all Toys objects of certain Parent?
Now I query all Children first and then I query the Toys of each Child and add them to a list or dict. But it's not really an elegant way...
I imagine something simple like (Flask_SQLAlchemy)
Toys.query.filter(Toys.child.parent_id == 'some parent id')
Is it possible?
Thank you
Krystof
I expect to get a SQLAlchemy object containing all Toys of certain parent.
You can join Toy to Child and then Child to Parent (SQLAlchemy can work out how to do the joins, assuming you have configured relationships between all the models):
toys = (Toy.query
.join(Child)
.join(Parent)
.filter(Parent.name == 'parent1')
)

django migrate primary OneToOneFiled ForeignKey + into composite foreign key

I've a model which is just a relation between two entities like this:
class SomeModel(models.Model):
a = OneToOneField(User,primary_key=True,...)
b = ForeignKey(Car,...)
As per design, it was correct, as I didn't want an User to have multiple Car. But in my new design, I want to accept multiple Car to an User. So I was trying something like this:
class SomeModel(models.Model):
class Meta:
unique_together = (("a", "b"),)
a = ForeignKey(User,...)
b = ForeignKey(Car,...)
But during migration, it asks me:
You are trying to add a non-nullable field 'id' to somenmodel without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
I just wanted to remove that foreign key from OneToOneRelation and add a new id combining both. - How to resolve this?
Delete the model and table from the database and create a new model from starting or add null=True to the given field. you must be having some data (rows) in your table and now you are creating a new column, so previous rows need something to be there in the newly created column, writing null = True will do that.

What is the best way to get information from DB?

Which query is better to get data form more than two tables by id field? use one joins on one query or many select statements?
I want to get the run time optimal solution.
For example:
I have "tasks" table that include foreign keys fields,
like: statustask (from statustasks table), taskurgency (from taskurgency table)
whate is the best way to get the "tasks" list object form DB:
with joins:
String sql = "SELECT * FROM tasks "
+ "INNER JOIN statustask_in_language ON tasks.status=statustask_in_language.statustask_id "
+ "INNER JOIN statustasks ON tasks.status=statustasks.id "
+ "INNER JOIN taskurgency_in_language ON tasks.urgency=taskurgency_in_language.taskurgency_id "
+ "INNER JOIN taskurgency ON tasks.urgency=taskurgency.id ";
List<task> listUsers = jdbcTemplate.query(sql, new RowMapper<task>() {
#Override
public task mapRow(ResultSet rs, int rowNum) throws SQLException {
task t = new task();
tabelsTemplate status=new tabelsTemplate();
tabelsTemplate urgency=new tabelsTemplate();
t.setId(rs.getString("id"));
t.setDate(rs.getTimestamp("date"));
t.setTargetDate(rs.getTimestamp("targetDate"));
t.setSubject(rs.getString("subject"));
t.setDescription(rs.getString("description"));
t.setAdminId(rs.getString("adminId"));
t.setOpenedBy(rs.getString("openedBy"));
status.setId(rs.getString("status"));
status.setInCurrentLanguage(rs.getString("statustask_in_language.description"));
status.setDescription(rs.getString("desc"));
t.setStatusObj(status);
urgency.setId(rs.getString("urgency"));
urgency.setInCurrentLanguage(rs.getString("taskurgency_in_language.description"));
urgency.setDescription(rs.getString("descUrgency"));
t.setUrgencyObj(urgency);
return t;
or use one join and select statments for each foreign key to set the object.
note: In Task object the foreign keys are objects (not Ids).
thank you!
This is a very general question, and can't be correctly answered with out the proper information like an example.
Every thing depends on which information you want, and what you want to do with it.
If you are required to get data from multiple tables, JOINS is the way to go, since it's the easiest way to connect data to each other without actually needing to do some unnecessary logic.
In most cases - JOIN will be the correct way, but then again, there are cases where the logic to align the data with PHP for example will be hard , and separate queries can be easier to use.

Forcing multiple JOINs

I have a CASE_MEMBER table with a row for each case member, and a field to indicate the member's role on the case. Let's say role 'Parent' and role 'Child'.
In the universe I've added the CASE_MEMBER table, and created a Parent object and Child object, each object containing a WHERE statement which specifies the correct value of the role field.
Now if I try and create a report with both of these objects, it will join to CASE_MEMBER only once, with a condition of "where role = 'Parent' and role = 'Child'", which is obviously impossible.
So I need to force the query to join to CASE_MEMBER once for each member type. Is the only way to do this by creating multiple aliases of CASE_MEMBER? Or is there another way to do this that also keeps my universe structure looking clean and more resembling the actual data model?
Create an alias of CASE_MEMBER, and include the WHERE condition in the join. So your joins will be:
For CASE_MEMBER to DEMOGRAPHICS:
case_member.member = demographics.memberid and case_member.role='child'
For CASE_MEMBER to DEMOGRAPHICS_PARENT (alias of DEMOGRAPHICS):
case_member.member = demographics_parent.memberid and case_member.role='parent'
Let's say you create (using the field names from your other question), a "Case ID" object from case_member.caseid, "Child SSN" from demographics.ssn, and "Parent SSN" from demographics_parent.ssn. Creating a report with all three of these objects will produce:
SELECT
case_member.caseid,
demographics.ssn,
demographics_parent.ssn
FROM
case_member,
demographics,
demographics demographics_parent
WHERE
(case_member.member = demographics.memberid
and case_member.role='child')
(and case_member.member = demographics_parent.memberid
and case_member.role='parent')
which should produce what you want.
Note that in this example, since we are including BOTH the child and parent table, we will get two rows in the result set. One with a blank child SSN and one with a blank parent SSN. To avoid this, you'd need to put a max() around each one.that

Querying many to many relationship with LinqToSQL

I have a database setup as follows (unfortunatelly was not allowed to publish diagram image in here so need to describe:
Responses table - contain RespondentID, QuestionID, ResponseOptionID
ResponseProperties - contain ResponsePropertyID, ResponsePropertyTypeID, Name
ResponsePropertyTypes - contain ResponsePropertyTypeID, Name
ResponsesInProperties (a many to many table) - contains ResponseID, ResponsePropertyID
There is a many to many relationship on ResponsesInProperties table. This table does not show in EF of course.
Say I have two response property types "Country" and "Wave" and corresponding ResponeProperties "USA", "UK" and "Wave2011", "Wave2012".
Now I need to get back from the database all (and not duplicated) responses that would be in USA and also in Wave2012. The trick is that every response I need must be in both Wave2012 and USA. I am trying to achieve this with LINQ to SQL. The below is Linq I came up with that get's me the correct records but they appear many times for different properties. Limiting the properties gives me no records whatsoever....
Any help appreciated!
var responses = from r in db.Responses
from rp in r.ResponseProperties
select new
{
RespondentID = r.RespondentID,
QuestionCode = r.Question.Code,
ResponseOptionCode = r.ResponseOption.Code,
ResponseOptionCodeName = r.ResponseOption.Text,
ResponsePropertyName = rp.Name,
ResponsePropertyTypeName = rp.ResponsePropertyType.Name
};
To clarify, you are trying to do this with LINQ to SQL and not EF as they have rather different models for M-M. With LINQ to SQL, you do have to include the middle join table.
The key thing missing from your query at this point is the filter (Where) clauses. You need to specify them for both sides of the join to properly filter the results. You indicate that when you supply a filter you get back no records. Can you clarify your question with that filter as it may help to fix your underlying problem.
Your query cannot produce unique responses because you also get ResponsePropertyName and ResponsePropertyTypeName, which will duplicate the results.
This entity framework query -
from r in db.Responses
where r.ResponseProperties.Any (rp => rp.Name == "USA")
where r.ResponseProperties.Any (rp => rp.Name == "Wave2012")
select new
{
RespondentID = r.RespondentID,
QuestionCode = r.Question.Code,
ResponseOptionCode = r.ResponseOption.Code,
ResponseOptionCodeName = r.ResponseOption.Text,
};
does produce unique Responses that are in USA and in Wave2012. The produced sql will show two EXISTS predicates with AND.