LINQ to Entities does not recognize the method 'Boolean Contains[Decimal] - asp.net-mvc

I am new to LINQ, so I am pretty confused here. I have a database and try to run following code.
IQueryable<decimal> location_ids = (from m in _db.Admins
where m.UserId.Equals("c5d3dc0e-81e6-4d6b-a9c3-faa802e10b7d")
select m.LocationId);
if (!location_ids.Contains(new Decimal(conf.umisteni.Budova.ID)))
On the if statement I get an error I don't understand, nor do I know, how to solve it:
System.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean Contains[Decimal](System.Linq.IQueryable`1[System.Decimal], System.Decimal)' method, and this method cannot be translated into a store expression.
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
Any ideas?

Using Linq-to-Objects IEnumerable will let you use Contains(Decimal) on the result of the query.
IEnumerable<decimal> location_ids = (from m in _db.Admins
where m.UserId.Equals("c5d3dc0e-81e6-4d6b-a9c3-faa802e10b7d")
select m.LocationId);
However, why not just expand the where clause:
IEnumerable<decimal> location_ids = (from m in _db.Admins
where m.UserId.Equals("c5d3dc0e-81e6-4d6b-a9c3-faa802e10b7d") && (m.LocationId == conf.umisteni.Budova.ID)
select m.LocationId);
if (!location_ids.Any())

Linq 2 sql cannot translate the ids.Contains() method to sql.
You could do the following:
if(!location_ids.ToList().Contains(new Decimal(conf.umisteni.Budova.ID)))
This will trigger the sql query, put them in objects and do the contains locally.
Another solution would be to put the conf.umisteni.Budova.Id in the Where clauses (with an equals, not a contains) and then add .any
if((from m in _db.Admins
where m.UserId.Equals(conf.umisteni.Budova.ID.ToString())
select m.LocationId).Any())
This would only be a good idea if you don't need any of the keys afterwards off course.

Here is a helper method that provides all of the goodness of .Contains() in the context of Linq to Entities
public static class LinqToEntitiesUtil
{
/// <summary>
/// Extension method that enables .Contains(obj) like functionality for Linq to Entities.
///
/// Source: http://www.velocityreviews.com/forums/t645784-linq-where-clause.html
/// </summary>
/// <typeparam name="TElement">The element being evaluated by the Where clause</typeparam>
/// <typeparam name="TValue">The value to match</typeparam>
/// <param name="valueSelector">Lamda for selecting matching values</param>
/// <param name="values">IEnumerable of the values</param>
/// <returns>Expression consumable by Linq to Entities that reflects semantics of .Contains(value)</returns>
/// <remarks>
/// Usage:
///
/// Replace expression like
///
/// where ChildrenIDs.Contains(items.CategoryID)
///
/// with
///
/// .Where((BuildContainsExpression<Item, int>(item => item.CategoryID, ChildrenIDs))
///
/// NOTE: If the item collection is large, the SQL query will be as well.
/// </remarks>
static public Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
if (null == valueSelector)
{
throw new ArgumentNullException("valueSelector");
}
if (null == values) { throw new ArgumentNullException("values"); }
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
{
return e => false;
}
var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
}

I just got bit by something similar. Your System.Data.dll might not be the same version. The method was supported on my dev machine, but then I got runtime errors when I deployed to a test machine. The System.Data.dll version was older. Backwards compatible methods are a good fix. But I would still want to track down the discrepancy, some patch must be applied that didn't on the other environments. Who knows what other issues this will cause down the road if left unchecked.

Related

Swashbuckle should use my controller action names as default summary

I am using Swashbuckle to generate my API definitions in a .NET 5 project.
To add a summary and remarks to my documentation, I am currently putting a comment on some of my actions like this:
/// <summary>
/// CreateSite
/// </summary>
/// <remarks>
/// Options:
/// * Enterprise = 0,
/// * Site = 1
/// * Order = 2
/// * Line = 3
/// * Product = 4
///
/// </remarks>
[HttpPost]
[Route("sites")]
public async Task<IActionResult> CreateSiteAsync([FromBody] SiteCreateRequest createRequest)
{ // My controller stuff }
This generates a nice documentation and is very helpful.
Howevery, my "summary" field has always the same value like my controller action name - I already put efford in a very good naming of the actions:
You can see above that the summary contains "CreateSite" and my controller name is "CreateSiteAsync".
Is there a way to automatize this?
So could I set some option in the service to use the controller name as a "default" summary option used in the json file?
Then I can just avoid this cumbersome comments in the all simple requests without the need of any docu.
I also use Swashbuckle and to properly document my APIs I use Swagger tags. Attached is an example of my actual use. For your specific controller name tag, in my example it would be [SwaggerOperation("In-Transit Shipments")]
/// <summary>
/// In-transit shipments
/// </summary>
/// <remarks>
/// Get in-transit shipments for a client
/// </remarks>
/// <returns></returns>
[SwaggerTag("GroundTransportation")]
[SwaggerOperation("In-Transit Shipments")]
[SwaggerResponse(200, typeof(List<LoadSummaryDto>), Description = "OK")]
[SwaggerResponse(400, typeof(ErrorMessageDto), Description = "Bad Request")]
[SwaggerResponse(404, typeof(ErrorMessageDto), Description = "Not Found")]
[SwaggerOperationProcessor(typeof(ReDocCodeSampleAppender), "Curl,CSharp,Java")]
[HttpGet("ShipmentInformation/In-Transit")]
[TraceAction(message: "Controller: Retrieving in-transit shipments for client", level: LogLevel.Information, externalErrorMessage: "In-transit shipments could not be found")]
public async Task<IActionResult> GetClientInTransitShipments(uint? page = GroundTransportationConstants.DefaultPage, uint? pageSize = GroundTransportationConstants.DefaultPageSize)
{
// ... a bunch of api code :-)
}

ASP.net Core WebAPI Routing order parameter condition

I've got have the following controller:
[Route("xapi/statements")] << -- NOTICE THE ROUTE
[Produces("application/json")]
public class StatementsController : ApiControllerBase
With he following actions
/// <summary>
/// Stores a single Statement with the given id.
/// </summary>
/// <param name="statementId"></param>
/// <param name="statement"></param>
/// <returns></returns>
[AcceptVerbs("PUT", "POST", Order = 1)]
public async Task<IActionResult> PutStatement([FromQuery]Guid statementId, [ModelBinder(typeof(StatementPutModelBinder))]Statement statement)
{
await _mediator.Send(PutStatementCommand.Create(statementId, statement));
return NoContent();
}
/// <summary>
/// Create statement(s) with attachment(s)
/// </summary>
/// <param name="model"></param>
/// <returns>Array of Statement id(s) (UUID) in the same order as the corresponding stored Statements.</returns>
[HttpPost(Order = 2)]
[Produces("application/json")]
public async Task<ActionResult<ICollection<Guid>>> PostStatements(StatementsPostModelBinder model)
{
ICollection<Guid> guids = await _mediator.Send(CreateStatementsCommand.Create(model.Statements));
return Ok(guids);
}
The actions are executed in the following order:
1. PutStatement
2. PostStatements
But PutStatement should only be triggered if the statementId parameter is provided. This is not the case.
I'm using 2 model binders to parse the content of the streams as either application/json or multipart/form-data if the statements have any attachments.
1. StatementPutModelBinder
2. StatementsPostModelBinder
How do i prevent the action from being excuted if the statementId parameter is not provided?
Eg. /xapi/statements/ => Hits PutStatement
I did not find a answer for my own question, but i made a mistake and was under the impression that the xAPI statements resource should allow statementId as a parameter for POST requests. Therefore i do not have the issue any more, which started my question.

Unity: Implicit ResolvedParameter for unnamed registrations

The UserService constructor has two parameters, a IUnitOfWork and a IUserRepository:
public UserService(IUnitOfWork unitofWork, IUserRepository userRepository)
{ ... }
I am using named registrations to differentiate between multiple instances of IUnitOfWork, so when registering the UserService with the Unity container, I need to explicitly specify the parameters using an InjectionConstructor:
container.RegisterType<IUserService, UserService>(
new InjectionConstructor(
new ResolvedParameter<IUnitOfWork>("someContext"),
new ResolvedParameter<IUserRepository>()
)
);
Is it possible for new ResolvedParameter<IUserRepository>() to be omitted? I would like Unity to implicitly deduce this parameter since there is no need for a named registration. The code would look like this:
container.RegisterType<IUserService, UserService>(
new InjectionConstructor(
new ResolvedParameter<IUnitOfWork>("someContext")
)
);
This would be done is any case when I don't need to use the InjectionConstructor.
Based on InjectionConstructor, I came up with this RequiredInjectionConstructor. It allows you to specify any set of arguments and it will attempt to find a constructor which is required to have (at a minimum) the passed set of injection parameters. If there are multiple constructors that meet this criteria, it chooses the constructor with the least number of parameters. The remaining constructor parameters are assumed to be unnamed resolved parameters.
I haven't performed a full suite of unit tests on it yet, so let me know if you encounter any issues.
/// <summary>
/// A class that holds the collection of minimum required
/// parameters for a constructor, so that the container can
/// be configured to call this constructor.
/// </summary>
public class RequiredInjectionConstructor : InjectionMember
{
private readonly List<InjectionParameterValue> _requiredParameterValues;
/// <summary>
/// Create a new instance of <see cref="RequiredInjectionConstructor"/> that looks
/// for a constructor with a minimum of the given required set of parameters.
/// </summary>
/// <param name="requiredParameterValues">The values for the parameters, that will
/// be converted to <see cref="InjectionParameterValue"/> objects.</param>
public RequiredInjectionConstructor(params object[] requiredParameterValues)
{
_requiredParameterValues = InjectionParameterValue.ToParameters(requiredParameterValues).ToList();
}
/// <summary>
/// Add policies to the <paramref name="policies"/> to configure the
/// container to call this constructor with the required parameter values.
/// </summary>
/// <param name="serviceType">Interface registered, ignored in this implementation.</param>
/// <param name="implementationType">Type to register.</param>
/// <param name="name">Name used to resolve the type object.</param>
/// <param name="policies">Policy list to add policies to.</param>
public override void AddPolicies(Type serviceType, Type implementationType, string name, IPolicyList policies)
{
ConstructorInfo ctor = FindConstructor(implementationType, _requiredParameterValues);
IEnumerable<InjectionParameterValue> selectedConstructorParameterValues = GetSelectedConstructorParameterValues(ctor, _requiredParameterValues);
policies.Set<IConstructorSelectorPolicy>(
new SpecifiedConstructorSelectorPolicy(ctor, selectedConstructorParameterValues.ToArray()),
new NamedTypeBuildKey(implementationType, name));
}
private static ConstructorInfo FindConstructor(Type typeToCreate, IEnumerable<InjectionParameterValue> requiredInjectionParameters)
{
var typeToCreateReflector = new ReflectionHelper(typeToCreate);
var matchedConstructors = typeToCreateReflector.InstanceConstructors.
Where(ctor =>
{
var constructorParameterTypes = ctor.GetParameters().Select(info => info.ParameterType);
return requiredInjectionParameters.All(required => constructorParameterTypes.Any(required.MatchesType));
});
if (matchedConstructors.Any())
{
// Prefer the constructor that has the least number of arguments.
// Other preference models could be implemented here.
return matchedConstructors.OrderBy(ctor =>
ctor.GetParameters().Count()).
FirstOrDefault();
}
string signature = string.Join(", ", requiredInjectionParameters.Select(required => required.ParameterTypeName).ToArray());
throw new InvalidOperationException(
string.Format("Unable to find a constructor with the minimum required parameters. Type: {0}, RequiredParameters: {1}",
typeToCreate.FullName,
signature));
}
private static IEnumerable<InjectionParameterValue> GetSelectedConstructorParameterValues(ConstructorInfo ctor, IEnumerable<InjectionParameterValue> requiredInjectionParameters)
{
var injectionParameterValues = new List<InjectionParameterValue>();
foreach (var parameter in ctor.GetParameters())
{
var existingInjectionParameter = requiredInjectionParameters.FirstOrDefault(required => required.MatchesType(parameter.ParameterType));
injectionParameterValues.Add(existingInjectionParameter ?? new ResolvedParameter(parameter.ParameterType));
}
return injectionParameterValues;
}
}
Would you be willing to decorate your constructor with the DependencyAttribute from Unity? This solution is straight forward, built-in, and lets you pick and chose named dependency. But it does 'dirty' your constructor with Unity goo.
public UserService(
[Dependency("someContext")]IUnitOfWork unitofWork,
IUserRepository userRepository)
{ ... }
Another solution would be to write a custom BuilderStrategy and UnityContainerExtension. This could be done with a bit more work.

Is there any advantage in using a "repository factory" with ASP.NET MVC4 and Entity Framework?

I am developing an application and I started to use as my base some code from an example by John Papa. Looking on the web I found this same code and it appears in an answer to a question on
Stackoverflow. Here is the question:
How to de-attach an entity from a Context in Entity Framework?
It's in the answer that was given by: SynerCoder
One part of the answer suggests the following class that is used to provide a repository from a dictionary of cached repositories. Can someone help me out and tell me is there really
an advantage in doing this. I understand the code but can't see the point of keeping repositories in a dictionary. Would it not be the case that every new web request would see an
empty dictionary and have to get / make a new repository anyway.
Data/Helpers/IRepositoryProvider.cs
using System;
using System.Collections.Generic;
using System.Data.Entity;
using Data.Contracts;
namespace Data.Helpers
{
/// <summary>
/// A maker of Repositories.
/// </summary>
/// <remarks>
/// An instance of this class contains repository factory functions for different types.
/// Each factory function takes an EF <see cref="DbContext"/> and returns
/// a repository bound to that DbContext.
/// <para>
/// Designed to be a "Singleton", configured at web application start with
/// all of the factory functions needed to create any type of repository.
/// Should be thread-safe to use because it is configured at app start,
/// before any request for a factory, and should be immutable thereafter.
/// </para>
/// </remarks>
public class RepositoryFactories
{
/// <summary>
/// Return the runtime repository factory functions,
/// each one is a factory for a repository of a particular type.
/// </summary>
/// <remarks>
/// MODIFY THIS METHOD TO ADD CUSTOM FACTORY FUNCTIONS
/// </remarks>
private IDictionary<Type, Func<DbContext, object>> GetFactories()
{
return new Dictionary<Type, Func<DbContext, object>>
{
//If you have an custom implementation of an IRepository<T>
//{typeof(IArticleRepository), dbContext => new ArticleRepository(dbContext)}
};
}
/// <summary>
/// Constructor that initializes with runtime repository factories
/// </summary>
public RepositoryFactories()
{
_repositoryFactories = GetFactories();
}
/// <summary>
/// Constructor that initializes with an arbitrary collection of factories
/// </summary>
/// <param name="factories">
/// The repository factory functions for this instance.
/// </param>
/// <remarks>
/// This ctor is primarily useful for testing this class
/// </remarks>
public RepositoryFactories(IDictionary<Type, Func<DbContext, object>> factories)
{
_repositoryFactories = factories;
}
/// <summary>
/// Get the repository factory function for the type.
/// </summary>
/// <typeparam name="T">Type serving as the repository factory lookup key.</typeparam>
/// <returns>The repository function if found, else null.</returns>
/// <remarks>
/// The type parameter, T, is typically the repository type
/// but could be any type (e.g., an entity type)
/// </remarks>
public Func<DbContext, object> GetRepositoryFactory<T>()
{
Func<DbContext, object> factory;
_repositoryFactories.TryGetValue(typeof(T), out factory);
return factory;
}
/// <summary>
/// Get the factory for <see cref="IRepository{T}"/> where T is an entity type.
/// </summary>
/// <typeparam name="T">The root type of the repository, typically an entity type.</typeparam>
/// <returns>
/// A factory that creates the <see cref="IRepository{T}"/>, given an EF <see cref="DbContext"/>.
/// </returns>
/// <remarks>
/// Looks first for a custom factory in <see cref="_repositoryFactories"/>.
/// If not, falls back to the <see cref="DefaultEntityRepositoryFactory{T}"/>.
/// You can substitute an alternative factory for the default one by adding
/// a repository factory for type "T" to <see cref="_repositoryFactories"/>.
/// </remarks>
public Func<DbContext, object> GetRepositoryFactoryForEntityType<T>() where T : class
{
return GetRepositoryFactory<T>() ?? DefaultEntityRepositoryFactory<T>();
}
/// <summary>
/// Default factory for a <see cref="IRepository{T}"/> where T is an entity.
/// </summary>
/// <typeparam name="T">Type of the repository's root entity</typeparam>
protected virtual Func<DbContext, object> DefaultEntityRepositoryFactory<T>() where T : class
{
return dbContext => new EFRepository<T>(dbContext);
}
/// <summary>
/// Get the dictionary of repository factory functions.
/// </summary>
/// <remarks>
/// A dictionary key is a System.Type, typically a repository type.
/// A value is a repository factory function
/// that takes a <see cref="DbContext"/> argument and returns
/// a repository object. Caller must know how to cast it.
/// </remarks>
private readonly IDictionary<Type, Func<DbContext, object>> _repositoryFactories;
}
}
Here's the code that calls the factory:
using System;
using Data.Contracts;
using Data.Helpers;
using Models;
namespace Data
{
/// <summary>
/// The "Unit of Work"
/// 1) decouples the repos from the controllers
/// 2) decouples the DbContext and EF from the controllers
/// 3) manages the UoW
/// </summary>
/// <remarks>
/// This class implements the "Unit of Work" pattern in which
/// the "UoW" serves as a facade for querying and saving to the database.
/// Querying is delegated to "repositories".
/// Each repository serves as a container dedicated to a particular
/// root entity type such as a <see cref="Url"/>.
/// A repository typically exposes "Get" methods for querying and
/// will offer add, update, and delete methods if those features are supported.
/// The repositories rely on their parent UoW to provide the interface to the
/// data layer (which is the EF DbContext in this example).
/// </remarks>
public class UnitOfWork : IUnitOfWork, IDisposable
{
public UnitOfWork(IRepositoryProvider repositoryProvider)
{
CreateDbContext();
repositoryProvider.DbContext = DbContext;
RepositoryProvider = repositoryProvider;
}
// Repositories
public IRepository<Event> Events { get { return GetStandardRepo<Event>(); } }
public IRepository<Candidate> Candidates { get { return GetStandardRepo<Candidate>(); } }
/// <summary>
/// Save pending changes to the database
/// </summary>
public void Commit()
{
//System.Diagnostics.Debug.WriteLine("Committed");
DbContext.SaveChanges();
}
protected void CreateDbContext()
{
DbContext = new UnicornsContext();
// Do NOT enable proxied entities, else serialization fails
DbContext.Configuration.ProxyCreationEnabled = false;
// Load navigation properties explicitly (avoid serialization trouble)
DbContext.Configuration.LazyLoadingEnabled = false;
// Because Web API will perform validation, I don't need/want EF to do so
DbContext.Configuration.ValidateOnSaveEnabled = false;
}
protected IRepositoryProvider RepositoryProvider { get; set; }
private IRepository<T> GetStandardRepo<T>() where T : class
{
return RepositoryProvider.GetRepositoryForEntityType<T>();
}
private T GetRepo<T>() where T : class
{
return RepositoryProvider.GetRepository<T>();
}
private UnicornsContext DbContext { get; set; }
#region IDisposable
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (DbContext != null)
{
DbContext.Dispose();
}
}
}
#endregion
}
}
It seems to me that the factory makes things more complicated that they need be. Am I correct and should I do this a simpler way such as with something like:
private IRepository<xx> = new GenericRepository<xx>(dbContext);
One more point. In my application I am using Unity. So would it be even easier to just specify the needed repositories in the constructor and have Unity create the repositories for me. If I did this then is there a way I could pass around the dbContext so it could be used by Unity when creating the repository? Has anyone used Unity to create repositories like this?
OK. Here's my best shot:
The point of keeping repositories in a cache is to ensure that the repository is only initiated once per request. The repository cache is in the RepositoryProvider class and is exposed to the UnitOfWork by the GetRepositoryForEntityType method. So the advantage is that the unit of work is not concerned with caching or creation of repositories.
The RepositoryProvider class is instantiated once per unit of work. (NB - it is desirable to create the repositories new for every request). The RepositoryProvider keeps the repositories in a dictionary using the type as a key. This is fine when using the generic repository base which has a Type parameter. But what if you have created a custom repository? In this example the creation of repositories by type is handed off to the RepositoryFactories class via the MakeRepository method. The advantage is that creating repositories is separated from caching.
The RepositoryFactories class knows when to make a custom repository because it contains a dictionary that uses Type as a key and a function as a value. The function is the constructor for a custom repository. If there's a value in the dictionary then use that constructor otherwise just use the generic base constructor.
All this means that as you add entities you do not have to modify any of these classes unless you create a custom repository. And when you do that all you have to do is add an entry to the dictionary in RepositoryFactories

Using MvcContrib TestHelper to assert that an inbound route should not be mapped

Looked for a method on the MvcContrib.TestHelper.RouteTestingExtensions class named ShouldNotMap. There is ShouldBeIgnored, but I don't want to test an IgnoreRoute invocation. I want to test that a specific incoming route should not be mapped to any resource.
Is there a way to do this using MvcContrib TestHelper?
Update
Just tried this, and it seems to work. Is this the correct way?
"~/do/not/map/this".Route().ShouldBeNull();
I think you are looking for the following:
"~/do/not/map/this".ShouldBeIgnored();
Behind the scenes this asserts that the route is processed by StopRoutingHandler.
I was looking for the same thing. I ended up adding the following extension methods to implement ShouldBeNull and the even shorter ShouldNotMap:
In RouteTestingExtensions.cs:
/// <summary>
/// Verifies that no corresponding route is defined.
/// </summary>
/// <param name="relativeUrl"></param>
public static void ShouldNotMap(this string relativeUrl)
{
RouteData routeData = relativeUrl.Route();
routeData.ShouldBeNull(string.Format("URL '{0}' shouldn't map.", relativeUrl));
}
/// <summary>
/// Verifies that the <see cref="RouteData">routeData</see> is null.
/// </summary>
public static void ShouldNotMap(this RouteData routeData)
{
routeData.ShouldBeNull("URL should not map.");
}
In GeneralTestExtensions.cs :
///<summary>
/// Asserts that the object should be null.
///</summary>
///<param name="actual"></param>
///<param name="message"></param>
///<exception cref="AssertFailedException"></exception>
public static void ShouldBeNull(this object actual, string message)
{
if (actual != null)
{
throw new AssertFailedException(message);
}
}

Resources