Have two classes. Books and Rating.
When user rates i am adding record to a Rating. Rating has a foreign key to Books.
Now, i want to calculate average of rating for the books using criteria language.
var bks = session.CreateCriteria(typeof(Books), "b")
.Add(Restrictions.Eq("b.CategoryId", id))
.CreateAlias("b.Rating", "r")
.SetProjection(Projections.Avg("r.RatingOne"))
.List<Books>();
When i run this, it shows an error :
could not resolve property: Rating of: Site.Models.Books
Related
Let's assume I have the following data model:
[Person]
Id - number
FirstName - string
LastName - string
[Director : Person]
YearlyIncome - number
[Employee : Person]
Age - number
[File]
Id - number
CreatedAt - date
AssignedTo - Person
As we can see the File entity has a field called AssignedTo which is a Person.
Now let's say I want to count the amount of Files by the FirstName of the Person, this works fine, because FirstName is a field the Person entity. The query would look like this, for example:
files?$apply=groupby((assignedTo/firstName),aggregate($count as count))
But now what I want is to be able to group by Age, a field on the Employee entity.
However if I use the following query:
files?$apply=groupby((assignedTo/age),aggregate($count as count))
I get the following error:
Could not find a property named 'age' on type 'App.Core.Entities.Person'.
According to OData Version 4.0 docs it should be possible (see 4.9).
I managed to get the query below to work, to select a field of a derived type:
/files?$expand=assignedTo($select=App.Core.Entities.Employee/Age)
But I can't apply this when using groupby, here's what I've tried:
$apply=groupby((assignedTo($select=App.Core.Entities.Employee/Age)),aggregate($count as count))
$apply=groupby((assignedTo/App.Core.Entities.Employee/Age)),aggregate($count as count))
$apply=groupby((assignedTo/App.Core.Entities.Employee/Age)),aggregate($count as count))
I guess the error makes sense, but I'm wondering what's the best way to solve this.
I'm trying to model a cataloging system in DynamodDB. It has "Catalogs" which contains "Collections". Each "Collection" can be tagged by many "Tags".
In an RDBMS I would create a table "Catalogs" with a 1:n relationship with "Collections". "Collections" would have an n:n with "Tags" as a Collection can have multiple Tags and a Tag can belong to multiple Collections.
The queries I want to run are:
1) Get all catalogs
2) Get catalog by ID
3) Get collections by catalog ID
I read on AWS I can use the adjacency list map design (because I have the n:n with "Tags"). So here is my table structure:
PK SK name
cat-1 cat-1 Sales Catalog
cat-1 col-1 Sales First Collection
cat-1 col-2 Sales Second Collection
cat-2 cat-2 Finance Catalog
tag-1 tag-1 Recently Added Tag
col-1 tag-1 (collection, tag relationship)
The problem here is I have to use a scan which I understand to be inefficient in order to get all "Catalogs" because a query's PK has to be an '=' and not a 'Begins With'.
The only thing I can think of is creating another attribute like "GSI_PK" and add "Catalog_1" when the PK is cat-1 and the SK is cat-1, "Catalog_2" when the PK is cat-2 and SK is cat-2. I've never really see this done so I'm not sure if it's the way to go and it takes some maintenance if I ever want to change IDs.
Any ideas how I would accomplish this?
In that case, you can have the PK be the type of the object and the SK be a uuid. A record would look like this { PK: "Catalog", SK: "uuid", ...other catalog fields }. You can then do a get all catalogs by doing a query on the PK = Catalog.
To store the associations you can have a GSI on two fields sourcePK and relatedPK where you could store records that associate things. To associate an object you would create a record like e.g. { PK: "Association", SK: "uuid", sourcePK: "category-1", relatedPK: "collection-1", ... other data on the association }. To find objects associated with the "Catalog" with id 1, you would do a query on the GSI where sourcePK = catalog-1.
With this setup you need to be careful about hot keys and should make sure you never have more than 10GBs of data under the same partition key in a table or index.
Let's walk through it. I'll use GraphQL SDL to layout the design of the data model & queries but you can just apply the same concepts to DynamoDB directly.
Thinking data model first we will have something like:
type Catalog {
id: ID!
name: String
# Use a DynamoDB query on the **Collection** table
# where the **catalogId = $ctx.source.id**. Use a GSI or make catalogId the PK.
collections: [Collection]
}
type Collection {
id: ID!
name: String
# Use a DynamoDB query on the **CollectionTag** table where
# the **collectionId = $ctx.source.id**. Use a GSI or make the collectionId the PK.
tags: [CollectionTag]
}
# The "association map" idea as a GraphQL type. The underlying table has a collectionId and tagId.
# Create objects of this type to associate a collection and tag in the many to many relationship.
type CollectionTag {
# Do a GetItem on the **Collection** table where **id = $ctx.source.collectionId**
collection: Collection
# Do a GetItem on the **Tag** table where **id = $ctx.source.tagId**
tag: Tag
}
type Tag {
id: ID!
name: String
# Use a DynamoDB query on teh **CollectionTag** table where
# the **tagId = $ctx.source.id**. If collectionId is the PK then make a GSI where this tagId is the PK.
collections: [CollectionTag]
}
# Root level queries
type Query {
# GetItem to **Catalog** table where **id = $ctx.args.id**
getCatalog(id: ID!): Catalog
# Scan to **Catalog** table. As long as you don't care about ordering on a filed in particular then
# this will likely be okay at the top level. If you only want all catalogs where "arePublished = 1",
# for example then we would likely change this.
allCatalogs: [Catalog]
# Note: You don't really need a getCollectionsByCatalogId(catalogId: ID!) at the top level because you can
# use `query { getCatalog(id: "***") { collections { ... } } }` which is effectively the same thing.
# You could add another field here if having it at the top level was a requirement
getCollectionsByCatalogId(catalogId: ID!): [Collection]
}
Note: Everywhere I use [Collection] or [Catalog] etc above you should use a CollectionConnection, CatalogConnection, etc wrapper type to enable pagination.
I have implemented Core data for storage in my App. I need to perform complex fetches using FetchRequest & predicate like below SQLite query:
SELECT
diagnosis_drug.drug_id,
diagnosis_drug.weight_bracket_id,
score,
localscore,
(score + localscore) AS score,
drug.*
FROM diagnosis_drug
INNER JOIN drug
ON diagnosis_drug.drug_id = drug.id
WHERE diagnosis_drug.doctor_id = 3
AND diagnosis_id IN (29, 212)
AND score > 0
AND weight_bracket_id = 1
AND diagnosis_drug._d = 0
ORDER BY score DESC
here diagnosis_drug & drug are entities and other are attributes.
Entity : Diagnosis_drug
Attributes :
diagnosisId - Int32
doctorId - Int32
drugId - Int32
score - Int32
localScore - Int32
Entity : Drug.
Attributes :
id : Int32
dosage : Int32
volume : Int32
genericName : String
formulation : String
doseType : String
duration : Int32
name : String
Drug's "id" attribute is equal to Diagnosis_drug's "drugId" attribute. The query is to get top score drugs from Diagnosis_drug and inner join is made to Drug entity to get its details.
So, I found out there are few limitations to core data . You can perform fetchrequest on two different entities only when they have a Relation between them. viz. if you have one-to-one relation between a Person(entity_1) and his mobile(entity_2) , to fetch both we need to perform a fetch on Person entity . To set filter on Person we'll add a Predicate as we need and to set filter on mobile , we'll put a "SUBQUERY" on mobile attributes in same predicate. If the two entities dont have a relation , there's a work around. You make those two entities as sub-entity of a new Parent entity, and perform a fetch on the new Parent entity ( See Reference! ). Still this leaves us with cases where those two entities already have some other Parents ! Here there is no relation as well as common Parent entity. So here is the limitation of Core data. You'll need to perform fetch on both such entities separately. Also Core data fetches don't allow computation inside query predicates(You'll need to maintain an extra variable in your entity and update that every time as you need). Any corrections on my findings are welcome . Thanks.
I have three tables
SalesDetails with columns SalesId, ProductId, Qty, Price etc
SalesPersonDtls with columns SalesId, SalesPersonId, CommPercentage etc
SalesPerson with columns SalesPersonId, firstName, lastName etc
I have second table because one sale can be done by more than one sales person together with split commission.
I have various inputs in search screen like productname, sales date, sales person name etc.
I am making the model class as 'AsQueryable' and add various where conditions and finally the result into a list.
I have sales person's name in search criteria but I don't know how to include this into the search. Can you please help?
Thanks
Peter
Peter
If I get it correct , relation of your business models is like this :
person (n) <-----> (1) Sale (1) <-----> (n) Details
you put sale and person relation in "SalesPersonDtls" and sale and detail relation to "SalesDetails". I think it's better to change your entities a little bit, if you want to get better result as your project getting bigger and more complex.
Your entities should be like this :
Sale
{
List<SalesDetail> details;
List<Person> persons;
...
}
SalesDetail
{
Sale
...
}
Person
{
Sale
name
...
}
Now it's really simple , if you want sales that is related to a personName :
sales.Where(sale => sale.Persons.Any(person => person.PersonName == "your input name"));
UPDATE :
If you can't or don't want to change your models:
first you need to find personId by it'name and then search into your "SalesPersonDtls" and get saleIds.
Following is my database architecture, three entities:
Load
ID_Load
From
To
Bids[]
Bid
ID_Bid
ID_Load
Amount
Load
Order
Order
ID_Order
Status
Amount
Bid
Load
Load and Bid : One to Many -- Load can receive multiple Bids
Order and Bid : One to One -- A single bid will be mapped with a order
Order and Load : One to One -- An order can have only one Bid
As you can see above I don't have ID_Load or ID_Bid properties in the order Entity as EF generate these automatically in the database, so the properties for these two fields are not added in the Order Entity
I am currenlty using Repository pattern with Code First in my project.
Now I want to get the Order information by ID_Load/ID_Bid (as there is a one to one relationship of Bid-Order and Load-Order table)
I don't want to run any SP or Select query in the application, but having issue while doing this.
If I run SQL I will have to write following query:
Select * from Order Where ID_Load = 123
Or
Select * from Order Where ID_Bid = 123
What is the alternative of this in EF/Repository Patterns in such situations.
Can anyone please help me with this.
Thanks,
Get order by Bid ID:
long bidId; // Id of Bid
var order = dbContext.Orders.Single(o => o.Bid.ID_Bid == bidId);
Get order by Load ID:
long loadId; // Id of Load
var order = dbContext.Orders.Single(o => o.Load.ID_Load == loadId);
If Bid and Load are optional for Order, use SingleOrDefault instead of Single. Single will throw an exception if the queried item does not exist, SingleOrDefault will return null.
Alternatively, if you need to load the Bid using its ID anyway:
var bid = dbContext.Bids.Find(bidId);
var order = bid.Order;
This can be optimized by forcing eager loading:
var bid = dbContext.Bids.Include(b => b.Order).SingleOrDefault(b => b.ID_Bid == bidId);
var order = bid.Order;