Enable ChangeTracking In Child Objects Using STE - self-tracking-entities

I'm using STE and I want to enable change tracking for an object and its children. What I currently have to do now is something like this.
int id = 1;
using(CustomerEntities context = new CustomerEntities())
{
CustomerSection custSection = context.CustomerSections.Include("CustomerSections.Customers").SingleOrDefault(p => p.ID == id);
custSection.StartTracking();
foreach(Customer cust in custSection.Customers)
{
cust.StartTracking();
{
return custSection;
}
What I am looking for is a way to automatically enable change tracking for the child objects too, without having to loop through each one and explicitly tell it to start tracking changes.
Thanks in advance for any insight.

Most probably you are using Self Tracking entities in combination with WCF. Then it's not needed to enable the changetracking manually. this is already done for you. The T4 template that generates the STE's includes a method decorated with the [OnDeserialized] attribute which starts the tracking once entities are deserialized (which occurs normally after reaching the client and converted back into runtime class instances fromout the xml that WCF generated for the transport. See the exact code example:
[OnDeserialized]
public void OnDeserializedMethod(StreamingContext context)
{
IsDeserializing = false;
ChangeTracker.ChangeTrackingEnabled = true;
}
Search your entities or the T4 template and you will find this soon.

Related

Exclude properties from rendering for all Grails domain classes

The Grails 2.5.4 docs say that it's possible to exclude properties from rendering for an entire group of domain classes.
There are some default configured renderers and the ability to register or override renderers for a given domain class or even for a collection of domain classes.
However there's no example given in the docs for how to do this. Does anyone know how to exclude properties for all of my domain classes? Specifically I'm trying to get rid of the class and enumType fields that Grails automatically adds to the response body.
There doesn't seem to be any good way to do this. What I discovered is that if you register an exclusion for a super class, all subclasses also "inherit" that exclusion. So to get rid of four properties for all Groovy objects (which cover all domain classes), I added the following bean to resources.groovy.
groovyObjectJsonRenderer(JsonRenderer, GroovyObject) {
excludes = ['class', 'declaringClass', 'errors', 'version']
}
I don't know if you are talking about this, but you can ignore some properties when you render as JSON, overriding the Marshaller here is the code:
static {
grails.converters.JSON.registerObjectMarshaller(NAMEOFYOURCLASS) {
return it.properties.findAll {k,v -> k != 'class' && k!='declaringClass'}
}
}
or if you want to create your custom render you can do something like this
static {
grails.converters.JSON.registerObjectMarshaller(NAMEOFYOURCLASS) {
def lista = [:]
lista['id'] = it.id
lista['name'] = it.name
lista['dateCreated'] = it.date?.format("dd/MM/yyyy HH:mm")
return lista
}
}
You can put it where you think its better i actually prefer to put it in the class i'm overriding, because letter i can find it or if some one else it's looking the code, he/she can find it easy.

Hard to update an Entity created by another LINQ to SQL context

Why this keep bugging me all day.
I have an entity with several references where i get from a context which I then Dispose.
Do some Changes and try to SubmitChanges(). While calling SubmitChanges() without .Attach() seems to simply do nothing. When using .Attach() I get the Exception :
An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.
Any ideas?
L2S is very picky about updating an entity that came from a different DB context. In fact, you cannot do it unless you 'detach' it first from the context it came from. There are a couple different ways of detaching an entity. One of them is shown below. This code would be in your entity class.
public virtual void Detach()
{
PropertyChanging = null;
PropertyChanged = null;
}
In addition to this, you can also serialize your entity using WCF based serialization. Something like this:
object ICloneable.Clone()
{
var serializer = new DataContractSerializer(GetType());
using (var ms = new System.IO.MemoryStream())
{
serializer.WriteObject(ms, this);
ms.Position = 0;
return serializer.ReadObject(ms);
}
}

What is the equivilant of C#'s generic Dictionary in ActionScript 3?

I want to have a collection of objects, which will be of a class I created called Server. A Server has a string property which is it's IP address, as well as many other pieces of data and objects.
I will have methods for adding and removing servers to this collection, and there will be a need to find a server by it's IP address occasionally. If I were doing this in C# I would use a Dictionary< where the IP string would be the key and the Server object would be the value. I could easily check to see if an item exists in the Dictionary before attempting to add it.
So my requirements are:
1. Ability to add items to the collection (I don't care where they go, front, back, middle)
2. Ability to remove items from anywhere in the collection.
3. Ability to determine if a particular IP address already exists in the collection.
4. Ability to get a reference to a Server object by it's IP.
Edit: Oh yes, I would like it to be strongly typed like the Vector... I guess it's not absolutely necesary, but would be nice.
So it seems like an associative arrays will give me what I need, except I'm not sure about how to do #3 or #4.
public var Servers:Object = new Object( );
public function AddServer(server:Server):void
{
//TODO:need to check if it exists first and throw an error if so
//(it's the caller's responsibility to call DoesServerExist first)
Servers[server.IP] = server;
}
public function RemoveServer(IP:string):void
{
//is it OK to attempt to delete an item if it doesn't already exist?
//do I need to check if it exists before doing delete?
delete Servers[IP];
}
public function DoesServerExist(IP:string):bool
{
//Do I loop through all the elements testing it's IP property?
//Or can I just do something like this?
if(Servers[IP] == null)
{
return false;
}
else
{
return true;
}
}
public function GetServer(IP:string):Server
{
return Servers[IP];//what is returned if this IP doesn't exist?
}
Call me goofy, but why not use the Dictionary class? That gets you everything except strong typing.
If you want strong typing then I'd say you need a custom container, which wraps up a Vector of Servers, and a Dictionary or associative array of IP strings that indexes into the Vector. Then you'd need to expose methods for access, test, insert and remove.
You can just use an array. Example:
var dict:Array = [];
var ip = "164.157.012.122"
dict[ip] = "Server name"
if (dict[ip] == "Server name"){
trace("Yay");
}
//membership
if (dict[ip]){
trace(ip + " is a member of dict");
} else {
trace (ip + " is not a member");
}
//removal:
dict[ip] = null;
AS3 does not really have a built in Dictionary class, unfortunately.

Linq to SQL and concurrency with Rob Conery repository pattern

I have implemented a DAL using Rob Conery's spin on the repository pattern (from the MVC Storefront project) where I map database objects to domain objects using Linq and use Linq to SQL to actually get the data.
This is all working wonderfully giving me the full control over the shape of my domain objects that I want, but I have hit a problem with concurrency that I thought I'd ask about here. I have concurrency working but the solution feels like it might be wrong (just one of those gitchy feelings).
The basic pattern is:
private MyDataContext _datacontext
private Table _tasks;
public Repository(MyDataContext datacontext)
{
_dataContext = datacontext;
}
public void GetTasks()
{
_tasks = from t in _dataContext.Tasks;
return from t in _tasks
select new Domain.Task
{
Name = t.Name,
Id = t.TaskId,
Description = t.Description
};
}
public void SaveTask(Domain.Task task)
{
Task dbTask = null;
// Logic for new tasks omitted...
dbTask = (from t in _tasks
where t.TaskId == task.Id
select t).SingleOrDefault();
dbTask.Description = task.Description,
dbTask.Name = task.Name,
_dataContext.SubmitChanges();
}
So with that implementation I've lost concurrency tracking because of the mapping to the domain task. I get it back by storing the private Table which is my datacontext list of tasks at the time of getting the original task.
I then update the tasks from this stored Table and save what I've updated
This is working - I get change conflict exceptions raised when there are concurrency violations, just as I want.
However, it just screams to me that I've missed a trick.
Is there a better way of doing this?
I've looked at the .Attach method on the datacontext but that appears to require storing the original version in a similar way to what I'm already doing.
I also know that I could avoid all this by doing away with the domain objects and letting the Linq to SQL generated objects all the way up my stack - but I dislike that just as much as I dislike the way I'm handling concurrency.
I worked through this and found the following solution. It works in all the test cases I (and more importantly, my testers!) can think of.
I am using the .Attach() method on the datacontext, and a TimeStamp column. This works fine for the first time that you save a particular primary key back to the database but I found that the datacontext throws a System.Data.Linq.DuplicateKeyException "Cannot add an entity with a key that is already in use."
The work around for this I created was to add a dictionary that stored the item I attach the first time around and then every subsequent time I save I reuse that item.
Example code is below, I do wonder if I've missed any tricks - concurrency is pretty fundamental so the hoops I'm jumping through seem a little excessive.
Hopefully the below proves useful, or someone can point me towards a better implementation!
private Dictionary<int, Payment> _attachedPayments;
public void SavePayments(IList<Domain.Payment> payments)
{
Dictionary<Payment, Domain.Payment> savedPayments =
new Dictionary<Payment, Domain.Payment>();
// Items with a zero id are new
foreach (Domain.Payment p in payments.Where(p => p.PaymentId != 0))
{
// The list of attached payments that works around the linq datacontext
// duplicatekey exception
if (_attachedPayments.ContainsKey(p.PaymentId)) // Already attached
{
Payment dbPayment = _attachedPayments[p.PaymentId];
// Just a method that maps domain to datacontext types
MapDomainPaymentToDBPayment(p, dbPayment, false);
savedPayments.Add(dbPayment, p);
}
else // Attach this payment to the datacontext
{
Payment dbPayment = new Payment();
MapDomainPaymentToDBPayment(p, dbPayment, true);
_dataContext.Payments.Attach(dbPayment, true);
savedPayments.Add(dbPayment, p);
}
}
// There is some code snipped but this is just brand new payments
foreach (var payment in newPayments)
{
Domain.Payment payment1 = payment;
Payment newPayment = new Payment();
MapDomainPaymentToDBPayment(payment1, newPayment, false);
_dataContext.Payments.InsertOnSubmit(newPayment);
savedPayments.Add(newPayment, payment);
}
try
{
_dataContext.SubmitChanges();
// Grab the Timestamp into the domain object
foreach (Payment p in savedPayments.Keys)
{
savedPayments[p].PaymentId = p.PaymentId;
savedPayments[p].Timestamp = p.Timestamp;
_attachedPayments[savedPayments[p].PaymentId] = p;
}
}
catch (ChangeConflictException ex)
{
foreach (ObjectChangeConflict occ in _dataContext.ChangeConflicts)
{
Payment entityInConflict = (Payment) occ.Object;
// Use the datacontext refresh so that I can display the new values
_dataContext.Refresh(RefreshMode.OverwriteCurrentValues, entityInConflict);
_attachedPayments[entityInConflict.PaymentId] = entityInConflict;
}
throw;
}
}
I would look at trying to utilise the .Attach method by passing the 'original' and 'updated' objects thus achieving true optimistic concurrency checking from LINQ2SQL. This IMO would be preferred to using version or datetime stamps either in the DBML objects or your Domain objects. I'm not sure how MVC allows for this idea of persisting the 'original' data however.. i've been trying to investigate the validation scaffolding in the hope that it's storing the 'original' data.. but i suspect that it is as only as good as the most recent post (and/or failed validation). So that idea may not work.
Another crazy idea i had was this: override the GetHashCode() for all of your domain objects where the hash represents the unique set of data for that object (minus the ID of course). Then, either manually or with a helper bury that hash in a hidden field in the HTML POST form and send it back to your service layer with your updated domain object - do the concurrency checking in your service layer or data layer (by comparing the original hash with a newly extracted domain object's hash) but be aware that you need to be checking for and raising concurrency exceptions yourself. It's nice to use the DMBL functions but the idea of abstracting away the data layer is so to not depend on the particular implementation's features etc. So having full control of the optimistic concurrency checking on your domain objects in your service layer (for example) seems like a good approach to me.

Maximum 'Units of Work' in one page request?

Its not One is it? I have a method that gets five Lists from different repositories. Each call opens and closes a new Datacontext. Is this ok to do or should I wrap everything in One datacontext. In this case it is not straightforward to use the same datacontext, but i am afraid that opening and closing numerous datacontext in one page request is not good.
Here is an article on just that subject...
Linq to SQL DataContext Lifetime Management
He recommends one per request and I have implemented that pattern in a few applications and it has worked well for me.
He talk a little about that in is article... His quick and dirty version makes a reference to System.Web and does something like this:
private TDataContext _DataContext;
public TDataContext DataContext
{
get
{
if (_DataContext == null)
{
if (HttpContext.Current != null)
{
if (HttpContext.Current.Items[DataContextKey] == null)
{
HttpContext.Current.Items[DataContextKey] = new TDataContext();
}
_DataContext = (TDataContext)HttpContext.Current.Items[DataContextKey];
}
else
{
_DataContext = new TDataContext();
}
}
return _DataContext;
}
}
But then he recommends you take the next step and get rid of the reference to System.Web and use dependency injection and create your own IContainer that could determine the life span of your datacontext based on whether your running in unit test, web application, etc.
Example:
public class YourRepository
{
public YourRepository(IContainer<DataContext> container)
{
}
}
then replace HttpContext.Current.Items[DataContextKey] with _Container[DataContextKey]
hope this helps...
I use on Unit of Work per request and built a IHttpModule that manages unit of work lifecycle, creating it on request and diposing it afterwards. The current unit of work is stored in HttpContext.Current.Items (hidden in Local.Data).