Partilhar via


EF POCO Adapter updated (v1.03)

I've just posted another round of updates to EF POCO Adapter based on feedback from users. This set of changes is focused on N-tier scenarios and detached entities (it adds missing wrappers for EF APIs and fixes behavior of existing ones).

Change log:

  • Added wrapper for ObjectContext.ApplyPropertyChanges() to IEntitySet<T>
  • Added wrapper for ObjectContext.Detach() to IEntitySet<T>
  • Fixed handling of detached/out-of-scope entities w.r.t lazy loading and attaching to other contexts. Lazy loading outside of scope will do nothing if the context had DeferredLoadingEnabled=false, otherwise will throw.
  • Added partial OnZZZCreated() methods on generated contexts, adapters and proxies to enable integration with 3rd-party extensions
  • Fixed code generation from EDMX.
  • EFPocoContext.EnableLazyLoading has been renamed to EFPocoContext.DeferredLoadingEnabled to better align with Linq to SQL and our plans for EF v2
  • Fixed adapter-POCO synchronization for complex types

The new release is here: https://code.msdn.microsoft.com/EFPocoAdapter/Release/ProjectReleases.aspx?ReleaseId=1580

Big thanks to everyone who sent me comments, bug reports and improvement suggestions for this release. This is very valuable feedback as it allows us to better understand user scenarios around POCOs for EF v2.

Comments

  • Anonymous
    September 25, 2008
    PingBack from http://hoursfunnywallpaper.cn/?p=7912

  • Anonymous
    October 09, 2008
    Was having trouble with the Generator, until I realised the filenames in the arguments are case sensitive. So classes.Dll failed to work but classes.dll did.

  • Anonymous
    October 11, 2008
    I'm having a little bit of trouble when trying to extend this sample with (what I would consider) a reasonable usage. The problem I encounter occurs after extracting an interface from a class in the model (say, Product : IProduct), and causes the TestMethod GenerateAndUsePocoAdapter() to fail. The error message given is: Test method NorthwindEF.Tests.AdapterGeneratorTests.GenerateAndUsePocoAdapter threw exception:  System.InvalidOperationException: Generated code failed to compile Errors (32): (2660,13): CS0506 'NorthwindEF.PocoProxies.ProductProxy.ProductID.get': cannot override inherited member 'NorthwindEF.Product.ProductID.get' because it is not marked virtual, abstract, or override It also appears that the generated code will fail to compile if one of the model classes implement an interface that exists within another assembly - for example Customer : IAggregateRoot (where IAggregateRoot is an interface that exists in an assembly referenced from the NorthwindEF project).

  • Anonymous
    October 20, 2008
    EntityClient Entity Framework != O/RM Sappiamo tutti che il buon vecchio pattern in un ADO.NET Data Provider

  • Anonymous
    November 21, 2008
    The comment has been removed

  • Anonymous
    November 21, 2008
    jlddodger: I am aware of this problem. Unfortunately fixing that is much harder than it seems, but there may be worksarounds. As part of the query translation EFPocoAdapter must translate queries in terms of POCO objects to use Adapter objects and generate a function that will convert the results back to POCO world. Translating POCO types to Adapter types is easy (there is 1-1 mapping between them and Adapter has all required properties of a POCO). Translating anonymous types is also doable, because C# compiler conveniently generates them using generic types where all property types are type arguments. Translating non-generic, non-entity types which have references to POCO entities is very hard as it would require a new type to be generated. You may be able to work around the problem by switching to LINQ to objects before final projection (by calling AsEnumerable()): var b = (from r in db.CustomerSet        where r.Name.Contains("AUTOMATED")        orderby r.Name select r) .AsEnumerable() .Select(c=> new Result() { Customer = c }); Let me know when it works for you. Jarek

  • Anonymous
    November 22, 2008
    Alright, that sounds reasonable for an explanation.  Just so that I am clear, calling AsEnumerable() will cross the Lazy Barrier and evaluate everything both on-the-client and eagerly.... is this correct? Proceeding from the assumption that that is correct, I was wondering if perhaps I could change the basic layout of the receiving class to function with the Member-Initializer-Assignment instead of changing to client-side evaluation.  For example, you had said that the reason anonymous types were possible is because the compiler instantiates a generic class where each parameter has a corresponding type to one of the generic class type parameters. First off, really awesome insight into C# for me.  Also, you said that it is easy to convert to an adapter type since it has all of the necessary parameters and the relationship to POCOs is one-to-one. Can I directly take advantage of these facts in any way?  Can I query for the adapter type? Or even declare my class as generic (hmm... can class type-parameters be used in member-initialization lists...) and construct it similar to an anonymous class type. If I am wrong about the performance change going to client-side evaluation, then just let me know.  I would love to find out that the easy answer is also the best.

  • Anonymous
    November 24, 2008
    Okay, just ignore the previous post.  I have determined through testing that deferred loading is not affected by crossing to client evaluation.  Also, because entire POCO objects are being requested (an entire Customer object), it makes no difference in network transfer amount whether the result object is constructed on the server- or client-side.  Technically, I believe it may be more efficient to construct the result object on the client-side.   Thank you for all your help.

  • Anonymous
    December 19, 2008
    Hi, I having a bit of problem. When trying to compile the generated PocoAdapters, I keep getting the following error: 'SomeClrNamespace.PocoAdapters.EntityAdapter' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TAdapterType' in the generic type or method 'EFPocoAdapter.DataClasses.PocoAdapterBase<TPocoClass>.DetectChanges<TAdapterType,TValue>(TValue, System.Data.Objects.DataClasses.EntityReference<TAdapterType>, string)' EntityAdapter and the Poco entity it targets, Entity are both abstract. Does DetectChanges absolutely need the 'new' constraint? Cause if does then the generated adapter cannot handle the case wherein an abstract class is the target of an EntityReference relationship. For instance in your sample NorthWindEF model, if Territory had a NavigationProperty back to the Employee, the generated Adapter wouldn't work. Can you recommend a work around? Many Thanks, Jimit Ndiaye

  • Anonymous
    December 22, 2008
    Is there any intention to support function imports in the generated Poco container?

  • Anonymous
    March 19, 2009
    Hello! First of all, thanks for the great job done with the poco adapter... I have found a problem for which I really hope you will help me... So here it is: I have following poco class: Group with long Id (primary key), string Name My problem is, that when I get the group from 2 contexts, even though they are the same, the method groups.Contains(group) returns false, but it should return true. HashSet<Group> groups = new HashSet<Group>(); using (MyEntities context1 = new MyEntities ()) {  Group group = context1.Groups.First(g => g.Id == 3);  groups.Add(group); } using (MyEntities context2 = new MyEntities ()) {  Group group = context2.Groups.First(g => g.Id == 3);  if (!groups.Contains(group)) {    groups.Add(group);  } } To make it work, I have override the GetHashCode method on the Group poco class: public override int GetHashCode() {  //Group id is a primary key  return Id.GetHashCode(); }   So the code works now. But I get exceptions from the PocoAdapter when trying to detach the group, or when calling DetectChanges, SaveChanges, etc. The exception is "InvalidOperationException("Entity is already attached with another active context. Cannot reattach.")" and comes from your method GetAdapterObject(...). When it calls _adapterObjects.TryGetValue(entity, out value), the value returned is null. As far as I can understand, you add the entities to the _adapterObjects dictionary and it adds them before they are filled with values... Could you please help me out?   Thanks a lot in advance. Kind regards Marc Wuergler

  • Anonymous
    April 12, 2010
    @wuwu1976, Please take a look at http://stackoverflow.com/questions/2626547/problem-with-custom-equality-in-entity-framework