I have an entity [Test]. It has many fields. These fields store huge data. (I use many CLOB, which is seralized to many [Transient fields]). In my application I need to show in a Grid a list of these tests (I show only Name and Date). But if I load all of tests from DB - my application require more and more memory. I want to load from Tests only Name and Date fields at first (and maybe pk Nr also). This info is enough to show in Grid. And then user select one Test and analyse it (analyse all necessary data). And now I need load all data for concrete Test. After user commit this Test - I need free memory of it in scope.
So, How I can clear all info about loaded/commited Test from scope?
5 Answers, 1 is accepted
To lazy load fields, you have to set the strategy to 'Lazy'. If you use the designer, just select the property and change it in the property window.
If you have a situation where you need more data immediately, please use the FetchStrategy to optimize the generate sql statements.
To free the memory, you have to dispose the scope. We are trying to keep our caches small by using weak references but you never know when the memory is freed.
All the best,
Jan Blessenohl
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's SQL Server Community Awards. We are competing in TWO categories and every vote counts! VOTE for Telerik NOW >>
my Entity:
public
class
TestGen : IInitializeTransients
{
[FetchField(
"fgTestGen"
)]
private
string
name;
public
string
Name
{
get
{
return
name; }
set
{ name = value; }
}
[FetchField(
"fgTestGen"
)]
private
DateTime testBegin;
public
DateTime TestBegin
{
get
{
return
testBegin; }
set
{ testBegin = value; }
}
public
string
CLOBData{
get
;
set
;}
// it is a CLOB-field
//....
}
FetchPlan.cs:
public
class
FetchPlans
{
public
static
FetchPlan fpTestGen =
new
FetchPlan(
new
string
[] {
"fgTestGen"
},
FetchPlan.DefaultMaxDepth,
FetchPlan.NoLimit ) ;
}
ScopeProvider.cs:
static
public
IObjectScope ObjectScope()
{
// ...
scope.FetchPlan.Clear();
scope.FetchPlan.Add(
"fgTestGen"
);
scope.FetchPlan.MaxDepth = 3;
return
scope;
}
but when I load TestGen from db:
var result = from p
in
scope.Extent<TestGen>() select p;
Also InitializeTransient-methods are called too. I don't need it too.
What I do incorrect?
Thanks!
You are using the debugger ;)
Our lazy loading code is injected into your properties, this means if the debugger shows the content of the properties in the watch window, the data is loaded. To see the real situation you have to switch off property evaluation in the Tools->Options->Debugging window.
Kind regards,
Jan Blessenohl
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's SQL Server Community Awards. We are competing in TWO categories and every vote counts! VOTE for Telerik NOW >>
If I switch off property evaluation in the Tools->Options->Debugging window - I can't see even my FetchFields!
Where I have to see and check - my FetchFields are initialized, but others - not. ??
You are right, analyzing loaded fields if you use auto puberties is complected. I have written two static functions that you can call in your debugger or in your application to print the field status to console or to the debugger windows:
private
static
void
DumpLoadedFieldsConsole(Object obj)
{
var ret = GetLoadedFields(obj);
foreach
(var t
in
ret)
{
if
(t.Item2)
Console.WriteLine(
"Field: "
+ t.Item1 +
" is loaded."
);
else
Console.WriteLine(
"Field: "
+ t.Item1 +
" is notloaded."
);
}
}
private
static
void
DumpLoadedFieldsDebugger(Object obj)
{
var ret = GetLoadedFields(obj);
foreach
(var t
in
ret)
{
if
(t.Item2)
System.Diagnostics.Debug.WriteLine(
"Field: "
+ t.Item1 +
" is loaded."
);
else
System.Diagnostics.Debug.WriteLine(
"Field: "
+ t.Item1 +
" is notloaded."
);
}
}
private
static
List<Tuple<
string
,
bool
>> GetLoadedFields(
object
obj)
{
var ret =
new
List<Tuple<
string
,
bool
>>();
var pc = obj
as
Telerik.OpenAccess.SPI.dataobjects.PersistenceCapable;
var pmp = pc.OpenAccessEnhancedGetPersistenceManager();
// call OpenAccessRuntime.DataObjects.PMProxy.getRealPM return OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp
var runtimeAssemly = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName.StartsWith(
"Telerik.OpenAccess.Runtime,"
)).Single();
var pmpType = runtimeAssemly.GetTypes().Where(x => x.FullName ==
"OpenAccessRuntime.DataObjects.PMProxy"
).Single();
var method = pmpType.GetMethod(
"getRealPM"
);
var pm = method.Invoke(pmp,
null
);
// OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.GetInternalStateManagerNoException returns OpenAccessRuntime.DataObjects.PCStateMan
var pmImpType = runtimeAssemly.GetTypes().Where(x => x.FullName ==
"OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp"
).Single();
method = pmImpType.GetMethod(
"GetInternalStateManagerNoException"
);
var stateMan = method.Invoke(pm,
new
object
[] { pc });
// access OpenAccessRuntime.DataObjects.PCStateMan.state return OpenAccessRuntime.common.State
var stateManType = runtimeAssemly.GetTypes().Where(x => x.FullName ==
"OpenAccessRuntime.DataObjects.PCStateMan"
).Single();
var field = stateManType.GetField(
"state"
, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var state = field.GetValue(stateMan)
as
OpenAccessRuntime.common.State;
var cmd = state.getClassMetaData();
foreach
(var fmd
in
cmd.fields)
{
var loaded = state.containsField(fmd.stateFieldNo);
ret.Add(
new
Tuple<
string
,
bool
>(fmd.PropertyName??fmd.name,loaded));
}
return
ret;
}
You have to add a reference to the Telerik.OpenAccess.Runtime assembly.
Best wishes,
Jan Blessenohl
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's SQL Server Community Awards. We are competing in TWO categories and every vote counts! VOTE for Telerik NOW >>