I need to repeatedly execute same queries which returns single entity by id,
like:
Customer cust = (from c in db.Customers
where c.CustomerID=="AIRBU"
select c).SingleOrDefault();
DLinq holds tracked object list internally so customer "AIRBU" exists in
memory.
How to force DLinq to look its list and not to make round trip to server ?
I looked into Entity Framework also but havent found any caching solution in
EF.
Andrus. 19 1488
"LINQ in Action" states that Single() is an exception, in that it
checks the cache first, not the database. I haven't tried it yet (long
day...) - but worth a try ;-p
(I'm assuming that SingleOrDefault doesn't qualify for this exception
since you've tried it... - and it would presumably need the predicate
to be based solely on the primary key column[s])
Marc
OK; I couldn't find a single case when Single() did anything other
than hit the database... I wonder what the authors had in mind?
Anyways... here is something truly, truly hacky that does the job; I'm
off to lather...
using System;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using WindowsFormsApplication4; // ns to DataClasses1DataContext =
Northwind
static class DataContextExt {
public static T GetFromCache<T>(this Table<Ttable, params
object[] keyValues) where T : class
{
if (table == null) throw new ArgumentNullException("table");
return GetFromCache<T>(table.Context, keyValues);
}
public static T GetFromCache<T>(this DataContext context, params
object[] keyValues) where T : class
{
// surfactants on standby - this is dirty, plain and simple
// (oh, and brittle, and not compile-time safe, and requires
// sufficient trust... you get the idea; nasty nasty nasty)
if (context == null) throw new
ArgumentNullException("context");
const BindingFlags FLAGS = BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic;
object services = context.GetType().GetProperty("Services",
FLAGS).GetValue(context, null);
object[] args = { context.Mapping.GetMetaType(typeof(T)),
keyValues };
Type[] paramTypes = { typeof(MetaType), typeof(object[]) };
return (T)services.GetType().GetMethod("GetCachedObject",
FLAGS, null, paramTypes, null).Invoke(services, args);
}
}
static class Program
{
static void Main()
{
using (DataClasses1DataContext ctx = new
DataClasses1DataContext())
{
// cache the original
Supplier sup = ctx.Suppliers.First();
int id = sup.SupplierID;
// get from the context
Supplier same = ctx.GetFromCache<Supplier>(id);
Trace.WriteLine(ReferenceEquals(sup, same), "Got from
Context");
// get from the table
Supplier again = ctx.Suppliers.GetFromCache(id);
Trace.WriteLine(ReferenceEquals(sup, again), "Got from
Table");
// and check what happens if it isn't there...
Supplier nothing = ctx.GetFromCache<Supplier>(53);
Trace.WriteLine(ReferenceEquals(nothing, null), "Null when
missing");
}
}
}
Marc,
OK; I couldn't find a single case when Single() did anything other
than hit the database... I wonder what the authors had in mind?
MSDN clearly states that every simple query must return result form identity
cache if it exists, not reaching to database.
Do you have any idea why it is not working ?
How to use identity cache in documented way ?
Anyways... here is something truly, truly hacky that does the job; I'm
off to lather...
Where did you found information which allows to create such program ?
I havent found any documentation on Services property and GetCachedObject
method.
Andrus.
MSDN clearly states that every simple query must return result form identity
cache if it exists, not reaching to database.
Can you cite a source there?
Do you have any idea why it is not working ?
How to use identity cache in documented way ?
I have asked that very question on a LINQ group; no answer yet...
Where did you found information which allows to create such program ?
From grubbling around... it is dirty and brittle (i.e. it will break if
somebody [quite reasonably] refactors the internal implementation)...
Marc
MSDN clearly states that every simple query must return result form identity
cache if it exists, not reaching to database.
(in particular - yes it should return the same instance from the cache
[and it does] - the question is focused around whether it hits the db...
can you cite a page for the above claim?)
>MSDN clearly states that every simple query must return result form
>identity cache if it exists, not reaching to database.
(in particular - yes it should return the same instance from the cache
[and it does] - the question is focused around whether it hits the db...
can you cite a page for the above claim?)
http://msdn2.microsoft.com/en-us/library/bb399376.aspx
Quote:
If the object requested by the query is easily identifiable as one already
retrieved, no query is executed. The identity table acts as a cache of all
previously retrieved objects.
Andrus.
So I guess it comes down to defining "easily identifiable"... I'll run
some more tests at some point (not "right now"), but I don't know how
easy / hard it will be to get working... which is why I am trying to get
some input from the LINQ people...
Marc
Marc,
So I guess it comes down to defining "easily identifiable"... I'll run
some more tests at some point (not "right now"), but I don't know how easy
/ hard it will be to get working... which is why I am trying to get some
input from the LINQ people...
id == constant expression if definitely "easily identifiable".
So it seems that we have found serious bug in Linq-SQL.
Can we submit product feedback to Microsoft?
Is it reasonable to subclass DataContext to fix this ?
There is also bug in "Linq in Action" book if it states that cache works
only with Single(). Ca we inform author about this ?
Andrus.
Can we submit product feedback to Microsoft?
Feel free ["connect", or the managed LINQ forum]; personally I'd like
to do a little more looking first...
Is it reasonable to subclass DataContext to fix this ?
The cache is internal, not protected. Subclassing won't help.
Ca we inform author about this ?
Authors plural; but I guess I can try to find some e-mail addresses
and see what they say...
Marc
For info, looked at the EF offering... unfortunately it is harder to
profile, and I don't have my SQL profiler handy; following gets the
right objects at least - but I don't know (until I get a few seconds
to switch servers) how many times it hits the database:
using System;
using System.Data;
using System.Data.Objects.DataClasses;
using System.Linq;
using AdventureWorksModel;
static class Program
{
[STAThread]
static void Main()
{
AdventureWorksEntities1 ctx = new AdventureWorksEntities1();
string setName = GetEntitySetName<Customer>(false),
qualifiedSetName = GetEntitySetName<Customer>(true),
keyName = GetKeyName<Customer>();
// expect DB hit here
var cust = ctx.Customer.First();
var id = cust.CustomerID;
// look by known key
EntityKey key = ctx.GetEntityKey(setName, cust);
var byKey = ctx.GetObjectByKey(key);
object obj;
if (ctx.TryGetObjectByKey(key, out obj))
{
var cust1 = (Customer)obj;
Console.WriteLine("Got...");
}
// look by custom key and a new ctx (assume a single primary
key for keyName)
AdventureWorksEntities1 ctx2 = new AdventureWorksEntities1();
EntityKey customKey = new EntityKey(qualifiedSetName, keyName,
id);
// (different instance, but it works...; expect another DB hit
here)
var cust2 = ctx2.GetObjectByKey(customKey);
// look using predicates
var cust3 = ctx.Customer.Where(x =x.CustomerID ==
id).First();
var cust4 = ctx.Customer.First(x =x.CustomerID == id);
}
static string GetEntitySetName<T>(bool qualified) where T :
EntityObject
{
EdmEntityTypeAttribute attrib =
(EdmEntityTypeAttribute)Attribute.GetCustomAttribu te(typeof(T),
typeof(EdmEntityTypeAttribute));
if (attrib == null) return null;
return qualified ? (attrib.NamespaceName + "." +
attrib.Name) : attrib.Name;
}
static string GetKeyName<T>() where T : EntityObject
{
return ( from prop in typeof(T).GetProperties()
let attrib = (EdmScalarPropertyAttribute)
Attribute.GetCustomAttribute(prop,
typeof(EdmScalarPropertyAttribute))
where attrib != null && attrib.EntityKeyProperty
select prop.Name).Single();
}
}
Marc,
For info, looked at the EF offering... unfortunately it is harder to
profile, and I don't have my SQL profiler handy; following gets the
right objects at least - but I don't know (until I get a few seconds
to switch servers) how many times it hits the database:
Thank you. Have you got any idea why Linq-SQL does not use cache ?
Andrus.
No; I've been invited to log a "connect" bug about it - I just want to
make sure I can't get it to work first...
Marc
On Apr 23, 4:38*pm, Marc Gravell <marc.grav...@gmail.comwrote:
Can we submit product feedback to Microsoft?
Feel free ["connect", or the managed LINQ forum]; personally I'd like
to do a little more looking first...
Is it reasonable to subclass DataContext to fix this ?
The cache is internal, not protected. Subclassing won't help.
Ca we inform author about this ?
Authors plural; but I guess I can try to find some e-mail addresses
and see what they say...
Marc
Andrus, thanks for letting us know about this issue. I suspect the
confusion stems from a change between the betas and the final RTM of
LINQ to SQL. I'm trying to get confirmation from the product teams and
will let you know if we find otherwise. If you find other issues with
the LINQ in Action book, feel free to let us know in our forum at http://www.manning-sandbox.com/forum.jspa?forumID=302. Also, we do
have an errata list at http://linqinaction.net/blogs/main/p...on-errata.aspx
which we will update once we receive confirmation on this issue.
Jim Wooley www.ThinqLinq.Com www.LinqInAction.net
Now that is service with a smile! Anything you can find out would be
appreciated...
Loving the book, btw.
Marc
Do you have any more information about this issue ?
My response is already on connect (from ages ago). I know nothing more. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Lei Jiang |
last post by:
1) Is it support other database other than SQL Server, such as Oracle,
Sybase?
2) How about the performance? Does it relay on reflections to bind the value
from databse to Entity object?
...
|
by: Senna |
last post by:
Hi
Have a question about DLinq.
The example code floating around looks like this:
Northwind db = new Northwind(@"C:\...\northwnd.mdf");
var custs = from c in db.Customers where c.City ==...
|
by: Chiranjib |
last post by:
I have the following queries/Observations about DLINQ.
1. I could not find any direct way of handling many to many relations.
Suppose if User and Role are related by a join table UserRole then I...
|
by: Scott Nonnenberg [MSFT] |
last post by:
This is our first official DLinq chat. We're still early in the planning and
development stage for this very cool technology, so we can react to your
feedback much more easily. Show up and tell us...
|
by: Scott Nonnenberg [MSFT] |
last post by:
The DLinq team will be ready and waiting for your questions and comments at
this date and time at this location:
http://msdn.microsoft.com/chats/chatroom.aspx. This is otherwise known as a
chat -...
|
by: Scott Nonnenberg [MSFT] |
last post by:
Show up and talk to members of the DLinq team. What's DLinq, you ask? Well,
to understand that you'll need to know what LINQ is - you can start with the
blurb below, read more about it here:...
|
by: Brett Romero |
last post by:
I've downloaded the DLINQ samples from Microsoft and have always been
able to compile these in VS.NET 2005 Pro. I have a new project that I
added DLINQ references to and put in a simlpe query. It...
|
by: Marc Gravell |
last post by:
How to fix ?
Write it the way that you know works... (i.e. the one you commented
out), or write that parses the input string doing a Split on '.', and
uses reflection to navigate the child...
|
by: Andrus |
last post by:
I need to create Dlinq entity property value caches for every entity and
every property so that
all entity caches can cleared if entity of this type is changed. Entity
class method uses this as:...
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: tracyyun |
last post by:
Hello everyone,
I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
|
by: giovanniandrean |
last post by:
The energy model is structured as follows and uses excel sheets to give input data:
1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
|
by: NeoPa |
last post by:
Hello everyone.
I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report).
I know it can be done by selecting :...
|
by: Teri B |
last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course.
0ne-to-many. One course many roles.
Then I created a report based on the Course form and...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM)
Please note that the UK and Europe revert to winter time on...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
|
by: isladogs |
last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, Mike...
| |