Why don't I have SubmitChanges? - asp.net-mvc-3

Is this something that's been changed in MVC 3? There is no SubmitChanges() method anywhere and I can't figure out, I seem to have the proper namespace too (System.Data.Linq).
The only thing I find is SaveChanges() instead. Are they the same? Or have I run into something strange here?

They are conceptually the same, although their implementations are different.
SaveChanges is part of ObjectContext in Entity Framework.
SubmitChanges is part of DataContext in Linq to SQL.

Related

Why is AutoMapper failing due to mappings in unrelated models?

I've inherited an MVC 3 project that uses AutoMapper. It appears to use nothing but the default Automapper configuration (I can't find any other configuration for Automapper anywhere in the solution, in other words). So I've written code like this for two new models I've added to the project:
Mapper.CreateMap<Entities.Document, Models.Attachment>();
Mapper.AssertConfigurationIsValid();
return Mapper.Map <List<Entities.Document>, List<Models.Attachment>>(Attachments);
Which ought to work fine - but the problem is that Automapper fails because of an inability to map completely unrelated objects. In other words, I get this message when Mapper.Map is called:
The following 2 properties on MyApp.Models.User are not mapped:
IsAdminUser
SubRoleList
Add a custom mapping expression, ignore, or rename the property on
MyApp.Entities.UserProfile.
Why is the mapping failing when Models.User has nothing to do with the models I'm mapping? They don't inherit from it. They don't contain any references to it. My new models are very simple models that contain a few strings and ints. MyApp.Models.User doesn't rely on them for anything, either.
I realize this problem can be solved by specifying the mappings in my AutoMapper calls. In fact, I've already done so, and it solves the problem. So I'm not worried about that. I can move on. What I'm worried about is that I can't figure out for the life of me why I'm getting this message when I try to use the default mapping. There are many other objects in the app which are very similar to the new objects I'm trying to map. They all work perfectly when code like the above is called. They don't require specifying any mappings and they don't have problems with MyApp.Models.User. I just want to know WHY this is happening because I want to understand it. Anyone got ideas? In case it's not obvious, I'm relatively new to MVC and Automapper. Thanks. :)
EDIT: Additional information:
If I add a call to Mapper.Reset() before the call to CreateMap(), everything works perfectly. I still don't understand why my method is the only method in the app that needs a Reset first.

What instantiate-able types implementing IQueryable<T> are available in .Net 4.0?

Within the context of C# on .Net 4.0, are there any built-in objects that implement IQueryable<T>?
IQueryable objects are produced by Queryable Providers (ex. LINQ to SQL, LINQ to Entities/Entity Framework, etc). Virtually nothing you can instantiate with new in the basic .NET Framework implements IQueryable.
IQueryable is an interface designed to be used to create Queryable providers, which allow the LINQ library to be leveraged against an external data store by building a parse-able expression tree. By nature, Queryables require a context - information regarding what exactly you're querying. Using new to create any IQueryable type, regardless of whether it's possible, doesn't get you very far.
That being said, any IEnumerable can be converted into an IQueryable by using the AsQueryable() extension method. This creates a superficially-similar, but functionally very different construct behind the scenes as when using LINQ methods against a plain IEnumerable object. This is probably the most plentiful source of queryables you have access to without setting up an actual IQueryable provider. This changeover is very useful for unit-testing LINQ-based algorithms as you don't need the actual data store, just a list of in-memory data that can imitate it.
Well, your question is kinda weird... but I believe that if you look at an interface in Reflector, it will give you a list of implementers in the loaded assemblies.
As a disclaimer I have not used Reflector since it went pay-for-play so I might be wrong.
EntityCollection does, as does EnumerableQuery.
Not that I think either of these is going to get you anywhere. To help, we need to know what you are really trying to solve. If you are writing a LINQ provider, you should read this: http://msdn.microsoft.com/en-us/library/bb546158.aspx.
They recommend writing your own implementation.
If you are looking for a way to instantiate an empty list of IQueryable, then you can use this:
IQueryable<MyEntity> = Enumerable.Empty<MyEntity>().AsQueryable()

Common LINQ method using EF

So this is probably a stupid question, but I am still not exactly sure how the entity frameworks objects work. I am using EF4 in an MVC3 app, and have two controllers that need to use the same LINQ query against it. Is it best to use a static method that takes the db entity by ref, or should the method use a "using" block for its own entity (as seen in this question)?
I would think the using block would add additional overhead, but I didn't find any examples of the other method. Is there a proper way to make "library" methods for EF access?
In an MVC application the ObjectContext should be scoped to the request. Most DI containers can do this automatically. So you would prefer not using a using block within a method. Instead inject the context via the constructor or pass it as a method argument.

calling database from domain entity objects

I'm having a go at using PetaPoco on a project rather than NHIbernate which I normally do, and I have a question about collections and using them from a domain model.
Lets say I have a BlogPost with Name and Text, and then Comments with Name, Author, Text
I want to associate BlogPost with Comments. I've done this in SQL with a Blogposts_Comments table. In NHibernate I'd just have a Comments collection on BlogPost and map that, which would then be retrieved or marked as Lazy.
I am thinking I might Lazy Load these Comments, so to do that, I'd call my data access object GetCommentsForBlogPost(this) in a Blog Post GetComments() method. My question is, is this considered good practice? Having your domain entities call the data access layer? in my NHibernate projects they just dealt with themselves as the NHibernate proxies/magic did the rest.
In my opinion, if you do this, you no longer have POCO objects.. whether or not that is a bad thing is really up to you. It's a tradeoff really between keeping your domain objects clean (arguably more maintainable), or making life only slightly easier for the caller.

Workarounds for using custom methods/extension methods in LINQ to Entities

I have defined a GenericRepository class which does the db interaction.
protected GenericRepository rep = new GenericRepository();
And in my BLL classes, I can query the db like:
public List<Album> GetVisibleAlbums(int accessLevel)
{
return rep.Find<Album>(a => a.AccessLevel.BinaryAnd(accessLevel)).ToList();
}
BinaryAnd is an extension method which checks two int values bit by bit. e.g. AccessLevel=5 => AccessLevel.BinaryAnd(5) and AccessLevel.binaryAnd(1) both return true.
However I cannot use this extension method in my LINQ queries. I get a runtime error as follows:
LINQ to Entities does not recognize the method 'Boolean BinaryAnd(System.Object, System.Object)' method, and this method cannot be translated into a store expression.
Also tried changing it to a custom method but no luck. What are the workarounds?
Should I get all the albums and then iterate them through a foreach loop and pick those which match the AccessLevels?
I realize this already has an accepted answer, I just thought I'd post this in case someone wanted to try writing a LINQ expression interceptor.
So... here is what I did to make translatable custom extension methods: Code Sample
I don't believe this to be a finished solution, but it should hopefully provide a good starting point for anyone brave enough to see it through to completion.
You can only use the core extension methods and CLR methods defined for your EF provider when using Entity Framework and queries on IQueryable<T>. This is because the query is translated directly to SQL code and run on the server.
You can stream the entire collection (using .ToEnumerable()) then query this locally, or convert this to a method that is translatable directly to SQL by your provider.
That being said, basic bitwise operations are supported:
The bitwise AND, OR, NOT, and XOR operators are also mapped to canonical functions when the operand is a numeric type.
So, if you rewrite this to not use a method, and just do the bitwise operation on the value directly, it should work as needed. Try something like the following:
public List<Album> GetVisibleAlbums(int accessLevel)
{
return rep.Find<Album>(a => (a.AccessLevel & accessLevel > 0)).ToList();
}
(I'm not sure exactly how your current extension method works - the above would check to see if any of the flags come back true, which seems to match your statement...)
There are ways to change the linq query just before EF translates it to SQL, at that moment you'd have to translate your ''foreign'' method into a construct translatable by EF.
See an previous question of mine How to wrap Entity Framework to intercept the LINQ expression just before execution? and mine EFWrappableFields extension which does just this for wrapped fields.

Resources