I've seen model defined functions used in in-code queries (queries written by the developer using Linq etc) and I'm wondering if there's any way to map a model-defined function to an entity property so that EF4 will automatically query the database using it.
For example:
Suppose I have a Product class and an Order class and that Product has a TotalSold property. Ideally I would like to create a model defined function like:
select sum(o.quantity) from order, product where o.productid = product.productid
and bind that to the TotalSold property of Product so that every query for a given Product would auto generate an inner select that would populate the TotalSold property.
Does this make sense? Is it possible?
I found a good-enough solution and blogged about it at http://statichippo.com/archive/2011/01/26/Mapping-a-computed-property-in-EF4.aspx
Related
Image I have following models:
class Product(models.Model):
name = models.CharField(max_length=20)
class Receipt(models.Model):
product = models.ForeignKey(Product)
user = models.ForeignKey(User)
I have an input list of product ids and a user. I want to query for each product, whether it's been purchased by this user. Notice I need a queryset with all exist products based on given input because there are other fields I need for each product even not purchased by this user, so I cannot use Product.objects.filter(receipt__user=user).
So can I create a temp Boolean field to present this property in one single query? I am using Django 1.8 and postgresql 9.3
Update requirements:To separate products into two groups. One is bought by this specific user, the other one is not. I don't think any given filter can implement this. This should be implement by creating a new temp field either by annotate or F expression.
I think, you need .annotate() expression as
from django.db.models.expressions import Case, When, Value
product_queryset = Product.objects.annotate(
is_purchased=Case(
When(receipt__user=current_user, then=Value('True')),
default=Value('False')
))
How to access the annotated field?
product_queryset.first().is_purchased
Thx for #JPG's answer.
I just realize except conditional expressions, there's another easy way to do it.
Just using prefetch_related will implement everything in two queries. Although it's double than conditional expressions, but it's still a considerable time complexity solution.
products = Product.objects.filter(id__in=[1,2,3,4,5]).prefetch_related ('receipt_set').all()
Then we can detect user for this product in Python by
for p in products:
print user in [receipt.user_id for receipt in p.purchase_set.all()]
I'm working on a proof of concept to explore how to connect SPARQL data from different data sources. I have two OWL classes, each from its own data model, representing information that I've extracted from two different systems. The data models look like:
Order: id, itemName, quantity
Item: id, name, unitPrice
What I would like to do is connect these two types together using the Order.itemName and Item.name fields, and create a new field on the Order class to store the total price for the order (order.quantity * item.unitPrice).
This would be pretty trivial to do with SPARQL, but we're looking at TopBraid Composer due to its graphical mapping capabilities. From my understanding, using a SPINMap we should be able to easily - and graphically - define the above property, but I'm having some problems getting things connected together.
I've been following the tutorial in the TBC Help under "Application Development Tools/SPIN/Ontology Mapping with SPINMap", but I'm having problems just trying to get a simple attribute mapped over. Based on that help document, on the Diagram tab I'm drawing a line from the Item Class to the Order class and selecting the changeNamespace function with an appropriate value. I then drew a line from the Item class to a new property on the Order class, totalPrice, and set the function to equals, just to see if I can get the property to show up. After running the inferences, I run a SPARQL query, and the totalPrice field is empty for all of my Order classes. I know this description was confusing - any idea what I should be doing to make this work?
Matt, in your second step are you using a property from the Item class to map to the Order class? That should work without any problems for the 'equals' template.
Check the Inferences tab in the middle-bottom row of tabs aster running inferences. This will show all materialized inferences and can be used to verift hat your SPINMap is doing what is desired.
Also look at Configure Inferencing to make sure the TopSPIN reasoner is chosen.
Every article I need to solve my problem seems to be in C# and I need a solution in VB.NET.
I'm using EF 6.0 with Database First model. Let me use the classic Customer product scenario to demonstrate my situation. In my database I have three tables Customer, Product and CustomerProduct. See this example in this link as mine is exactly the same.
After I generate my model from the database, my entity model diagram shows that the CustomerProduct has disappeared as expected and the the model shows a many to many relationship between Customer and Product also as expected with navigational properties of Products in Customer and Customers in Product.
All I want to do is find the product related to a customer pull out some data from both tables namely CustName and ProductName.
The SQL I would use is:
SELECT c.CustName, p.ProductName FROM Customer c
INNER JOIN CustomerProduct cp on c.CustomerId = cp.CustomerId
INNER JOIN Product p on cp.ProductId = p.ProductId
WHERE c.CustomerId=101
I don't know how to use the Addresses navigational property to access the Address data in one query.
You include them and then access them via the property in the Entity class.
Dim query = model.User.Include("Address").Include("UserAddressLink").Where(Function(o) o.UserId = 101).FirstOrDefault
If Not query Is Nothing Then
Dim houseNumber = query.Address.HouseNo 'uses the navigation property
End If
Thanks to InteXX I managed to work it out. This is my whole solution
Using db as new CustProdEntities
Dim query = db.Customers.Include(Function(U) U.Products).ToList
txtCustomer.Text = query.First.CustName
txtProduct.Text query.First.Products.First.ProdName
End Using
The bit I was stuck on was having to filter twice to the Product data. I'm not sure if there's an easier way to do this but it works for now.
I am trying to use Projections to Create a DTO from a Lead class. My DTO has, for example, a Home phone number, a mobile number and an email address, but the Lead Class has a collection of contact details. So I'm trying to find a way to retrieve each contact detail so that I can set the properties on the dto. I have tried using sub queries and projections but to no avail.
The SQL I'm trying to generate is something like this:
SELECT
A.LeadId,
B.ContactId,
B.Value,
C.ContactId,
C.Value,
D.ContactId
FROM Lead A
LEFT JOIN ContactDetail B ON A.LeadId=B.LeadId AND B.ContactType='Home Number'
LEFT JOIN ContactDetail C ON A.LeadId=C.LeadId AND C.ContactType='Mobile Number'
LEFT JOIN ContactDetail D ON A.LeadId=D.LeadId AND D.ContactType='Email Address'
So in short I'm trying to join to the same table 3 times based on different criteria, and I know that in NHibernate I can't use CreateAlias to join to the same table more than once and I'm anxious to know if this is possible using either the Criteria API or NHIbernate Linq. Thanks in advance for any help.
I would load the "regular" lead instance from nHibernate with its contact detail collection. Then I would use AutoMapper, to map it to the DTO class.
In my opinion, this is a much cleaner approach since you do not create special data access methods just for "simple" DTO mappings. And it's easier for refactoring since everything is expressed via "c sharp code".
Link to AutoMapper
Entities
We have an entity called Product which is loaded using NHibernate.
Product has a category which NHibernate happily populates for me.
Database
In the database, Product has a foreign key for category.
Scenario
User edits this Product (via a web interface) and chooses a different category (say instead of "Fish" we select "Veg").
This is probably a dropdown list, with each category shown. When they choose a different category we get an int key.
Problem
Obviously we now want to save the changes to Product but in effect the only change is to save a new int (say 2, instead of 1).
So we retrieve the existing Product, and now comes the problem.
We don't have a "CategoryID" field on Product, we only have a Category property.
But we don't really want to retrieve the category (by id) just to assign it to the Product.
So I guess what I want to know is should we...
a) Add a CategoryID property to Product
b) Create a new category, assign it the relevant id and attach that to Product (but surely that will cause errors, or overwrite the existing category)
c) Retrieve (lookup) the category from the system (by id) and attach that to the Product
d) Do something else entirely!
It looks like you might be able to using the Session.Load(id) functionality.
Session.Load is a special method that returns a proxy with the ID until you request another property at which point it loads. It throws an error if there is no item matching the ID. Try something like:
product.Category = Session.Load<Category>(2); //2 being the new category ID
Session.SaveOrUpdate(product);
I just did a little testing and it did not seem to pull back the entire Category.
Updated: Session.Load is the correct answer
product.Category = session.Load<Category>(2);
session.Save(product);
Use NH's EnumStringType<T> to map your Category as an enum to the respective database value (which can be a string or a number). You'll find quite a few usage examples, if you google for it.
HTH!