EF: How to query for local data - vb.net

This is EF4. I have a SIMPLE question. Say if I add a few sales orders to the context object like:
Dim NewOrder = context.SalesOrders.CreateObject()
NewOrder.Number= 123
context.SalesOrders.AddObject(NewOrder)
I haven't called SaveChanges() yet and want to see if there's an order with Number=123 in the context using this:
context.SalesOrder.FirstOrDefault(Function(x) x.Number=123)
Why in the world does this above query return Nothing? Is it searching the database instead of the local context object?

You can search the local entities through the object state manager: (C# syntax, but the VB.NET equivalent should be obvious for you)
context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Unchanged).Select(entry => entry.Entity).OfType<SalesOrder>()
That is actually what DbSet.Local does behind the scenes too. It may be worth the effort to make this available on your context as a generic helper function.

Is Number the primary key on the SalesOrder entity?
If so, you can just use .Find() as this first queries the local entities and only then queries the database if nothing is found in the local entities collection :
context.SalesOrders.Find(number);
Note that find can only accept the primary key and not lambdas as with other LINQ operations.

Related

Using the DoctrineObjectConstructor, how are new entities created?

I am attempting to use JMSSerializerBundle to consume JSON into Doctrine entities. I need to both create new entities where they do not already exist in the database, and update existing entities when they do already exist. I am using the DoctrineObjectConstructor included in the JMSSerializer package to help with this. When I consume JSON which contains a property designated as an identifier, such as:
{
"id": 1,
"some_other_attribute": "stuff"
}
by attempting to deserialize it, JMSSerializer causes warnings and eventually dies with an exception for attempting to utilize reflection to set properties on a null value. The warnings all look like this:
PHP Warning: ReflectionProperty::setValue() expects parameter 1 to be object, null given in /Users/cdonadeo/Repos/Ubertester/vendor/jms/serializer/src/JMS/Serializer/GenericDeserializationVisitor.php on line 176
If I manually insert an entity with ID 1 in my database and make another attempt then I receive no errors and everything appears to be working correctly, but I'm now short half my functionality. I looked at the code for the DoctrineObjectConstructor class, and at the top is a comment:
/**
* Doctrine object constructor for new (or existing) objects during deserialization.
*/
But I don't see how it could possibly create a new a new entity because after the construct() function has done all of its checks, at the end it calls:
$object = $objectManager->find($metadata->name, $identifierList);
And since the identifier does not exist in the database the result is null which is ultimately what gets returned from the function. This explains why inserting a row in the database with the appropriate ID makes things work: find() now returns a proper Entity object, which is what the rest of the library expects.
Am I using the library wrong or is it broken? I forked the Git repo and made an edit, and trying it out everything seems to work more or less the way I expected. That edit does have some drawbacks that make me wonder if I'm not just making this more difficult than it has to be. The biggest issue I see is that it will cause persisted and unpersisted entities to be mixed together with no way to tell which ones are which, but I don't know if that's even a big deal.
For Doctrine entities use configuration:
jms_serializer:
object_constructors:
doctrine:
fallback_strategy: "fallback" # possible values ("null" | "exception" | "fallback")
see configuration reference https://jmsyst.com/bundles/JMSSerializerBundle/master/configuration

How can I use ORMLite with objects that contain ArrayLists of other objects?

I have a Android java project with quite complex datatypes including ArrayLists of other complex datatypes. I’m trying to store my data in a database using ORMLite (4.42).
I have major problems converting between ArrayLists and ForeignCollection, has anyone manage to do this?
I don’t want a continuous sync with the database, instead I have a save method that saves the entire structure and a read method that restores the entire method. After an object is restored from the database, the object is sent via interfaces where the receiver expects a ArrayLists and not orm lite ForeignCollections.
My approach is the following. For each ArrayList I have a complementary ForeignCollection. Before storing an object to the database, the content of the ArrayList is copied to the ForeignCollection, and when read back, vice versa.
When I read out a data structure from the database, I want the ensure that the entire structure is restored since later on, the object will be sent to users that are not aware about orm lite package, thus I set eager = true.
My complex datatype looks like this:
#DatabaseTable(tableName = "accounts")
public class Account {
#DatabaseField(generatedId = true)
private int id;
#ForeignCollectionField (eager = true, maxEagerLevel = 2)
private ForeignCollection<Order> ordersFoC;
private ArrayList<Order> ordersArL;
The Problem
Before storing the Account to the database, I tried to do the following. My hope was to copy the objects in the ArrayList to the ForeignCollection and the update the database with the Account object. The object myAccount has the same id as an object in the database so I expect an update of that object.
ordersFoC.addAll(orderArL);
myDao.createOrUpdate(myAccount);
No luck. The addAll method does directly write the orders to the database so I end up with duplicates of all orders since “addAll” adds and does not update any existing records.
So I tried to first remove all the orders from the database, but again with no luck:
ordersFoC.clear(); // Also tried: ordersFoC.removeAll(ordersFoC);
ordersFoC.addAll(orderArL);
myDao.createOrUpdate(myAccount);
The objects are not removed from the database. I read at groups.google.com (by Philip Fu) that this is a “known” problem with ormlite, that eager ForeignCollection does not play well with removeAll() or clear().
Is there a pattern that I have missed that allows me to work with objects that includes ArrayLists of complex types using the ormlite framework?
I've got my code working with ArrayLists ok. I declared my fields like this:
#ForeignCollectionField(eager = true, maxEagerForeignCollectionLevel = 99)
private Collection<PersonalNameStructure> personalnamestructures = new ArrayList<>();
and the getter as
public List<PersonalNameStructure> getPersonalNameStructures() {
return new ArrayList<>(personalnamestructures) ;
}
so it creates the ArrayList on the fly rather than trying to maintain it.
Obviously you may realise this already, but you also need to be careful around writing the objects as the eager setting affects reading foreign collections, it doesn't do anything for foreign fields or when writing a record.

Spring.Net HibernateTemplate.Execute Clarification

I am taking over a project that was written by third party consultants who have already left.
I come from EF backgournd. One of the DAO class has the following which I find very hard to get my head around on details of what is exactly happening step by step. If anyone could kindly help me to understand this code section will be much appreciated.
return HibernateTemplate.Execute(
delegate(ISession hbSession) // <<--What is this code actually trying to do?
{
string queryText = "from {0} x where x.Code = :Code";
queryText = string.Format(queryText, typeof(Product));
IQuery query = hbSession.CreateQuery(queryText);
query.SetParameter("Code", productCode);
query.SetCacheable(true);
query.SetCacheRegion(CoreCacheConstants.ProductQueryCacheRegion); // <-- What is this code trying to do.
var fund = query.UniqueResult(); // <-- Is this similar to DISTINCT keyword in LINQ?
if (fund == null)
throw new ArgumentException(String.Format("No product found with productcode: {0}", productCode: ));
NHibernateUtil.Initialize(((Product)Product).Details); // <--What is this code trying to do. And where is the execute method for above queries.
return fund;
}
) as Product
Basically I am confused with delegate part and why delegate is being used instead of simple query to database. And what is the benefit of above approach.
Also I cant see any nHibernate ORM mapping xml. Does Spring.NET requires mapping files in order to pass data from/to data source?In order words how does ISession knows which database to connect to and which table to use etc
This is what in the spring documents is referred to as Classic Hibernate Usage. It is not the currently recommended approach to work with NHibernate, which is described in the chapter on object relational mappers.
The "convenient" usage of delegates here is basically done to provide the HibernateTemplate the means to manage a session and hand this managed session over to other custom methods (in this particular case an anonymous method). (I think it's an implementation of the visitor pattern, btw).
Using this approach, the classic HibernateTemplate can provide functionality to methods it doesn't "know of", such as opening and closing sessions correctly and participating in transactions.
The query is actually being executed by HibernateTemplate.Execute(myMethod); I imagine it creates and initializes a session for you, does transaction management, executes your method with the managed session and cleans everything up.
I've never used HibernateTemplate, but I'm sure it would require mapping files and a SessionFactory, so if this code is hit during execution and doesn't throw any exceptions, the configuration for those has to be there somewhere!
With respect to the questions (besides the delegate part) within your posted code: the use of NHibernateTemplate hasn't really got anything to do with it: you can just as well run this code in any piece of code where you've got hold of a valid ISession instance:
the session executes a HQL query; this query is added to the query cache. I've never used SetCacheRegion myself, but apparently it gives you "fine-grained control over query cache expiration policies".
query.UniqueResult
NHibernateUtil.Initialize

Hibernate configure how to create an object

Is it possible to configure Hiberate/NHibernate not to use the default constructor to create objects when reading from the database?
When Hibernate reads 10 customers from a table, it creates 10 Customer objects. It does this by
Customer c = new Customer();
Can I tell Hibernate to do the following instead:
Customer c = ACertainStaticFactory.CreateNewCustomer();
or even to manage a factory instance:
ACertainFactory factory = .....;
Customer c = factory.CreateNewCustomer();
or even more sophisticated, to pass a parameter which I set before:
// My client code
Query query = session.CreateQuery(...);
// either:
query.SetSomeParameter(someObject);
// or:
session.SetSomeParameter(someObject);
query.List();
// Hibernate should then behave like this:
Customer c = new Customer(someObject);
// or
Customer c = ACertainStaticFactory.CreateNewCustomer(someObject);
// etc.
Is that possible in anyway? If yes: How? If no: Is there an alternative?
When Hibernate reads 10 customers from a table, it creates 10 Customer objects. It does this by (...)
More precisely, Hibernate uses Class<T>#newInstance() to create new instances of an entity, which relies on the no-arg constructor. Hence the need to provide it.
Is that possible in anyway? If yes: How? If no: Is there an alternative?
Your requirement looks close to the Possible to have Hibernate hydrate objects with Factory? thread on Hibernate's forums so I'll quote Steve's answer (updated to match current names):
This is totally doable. In fact you
have two options:
create a custom EntityPersister implementation;
create a custom Interceptor implementation, specifically the
Interceptor.instantiate() method will
be of interest to you...
I think I'd go the interceptor way (not sure about your complex scenario but implementing the factory approach looks pretty easy).
Check this out, may be helpful:
http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html

Linq To SQL DAL and lookup data source

I am learning linq to sql and I am trying to setup a lookup combo box in my web page. I was using a linq data source but I then moved my linqtosql code to it's own class library for my DAL dll (took out of app_code folder). So, I am converting the page code to be able to still have lookups driven now by a biz object.
Here's what I have done in my biz layer...
Public Class KosherTypes
Public Shared Function GetKosherTypes() As List(Of KosherTypeLookup)
Dim db As New DBDataContext
Dim types = From kt In db.KosherTypes _
Where kt.IsDeleted = False _
Order By kt.Name _
Select New KosherTypeLookup With {.Name = kt.Name, .ID = kt.KosherTypeID}
Return types.ToList
End Function
End Class
I then setup an object data source and mapped it to this class.
I have a few questions as when I was doing internet searches I didn't find anyone that seemed to be doing this and yet I know lookup tables / combo boxes are common...
Did I totally just miss something and there are better way(s) to do this?
I went with returning a list but I could have returned an IEnumerable or IQueryable. In my reading it seemed IQueryable had more functionality for linq to sql but since I am returning a simple two column list then I only need to return an IEnumerable or List. I went with a List since it's strongly typed. Did I make a good decision? AKA - Should I just have returned and IEnumerable or perhaps gone with IQueryable?
Thanks!
I'll answer in reverse order:
I wouldn't use IQueryable outside of your repos / DAL for the simple reason that since execution is deferred, you lose control of what exactly is executed (i.e., an aribtrary function could be assigned as a delegate for WHERE), making maintenance and testing much harder. I don't see an issue with you returning an IEnumberable(Of KosherTypeLookup) though.
If the lookup is a static lookup that never or rarely changes, you might want to look at a way to cache the lookup after the first use, to avoid having to hit the db every time that box is called. It really depends on your expected load, though. As always, performance/load testing will highlight where you need to optimize.