EF Entity with TimeSpan property not supported in Breeze.js? - entity-framework

I am getting a NotSupportedException after I added a TimeSpan property to the Employee entity in the DocCode project. So I know it isn't supported but... Are there plans to do a conversion or a way to get past this. We use TimeSpan extensively in our entities, is there a way to support TimeSpan or plans to?
Added Duration property
public class Employee
{
...
public DateTime? HireDate { get; set; }
public TimeSpan? Duration { get; set; }
[MaxLength(60)]
public string Address { get; set; }
...
}
When the MetaData() method is called on the NorthwindController running the unit test it fails:
System.NotSupportedException was unhandled by user code
HResult=-2146233067
Message=There is no store type corresponding to the EDM type 'Edm.Time(Nullable=True)' of primitive type 'Time'.
Source=System.Data.SqlServerCe.Entity
StackTrace:
at System.Data.SqlServerCe.SqlCeProviderManifest.GetStoreType(TypeUsage edmType)
at System.Data.Entity.ModelConfiguration.Edm.Services.StructuralTypeMappingGenerator.MapTableColumn(EdmProperty property, DbTableColumnMetadata tableColumnMetadata, Boolean isInstancePropertyOnDerivedType, Boolean isKeyProperty)
at System.Data.Entity.ModelConfiguration.Edm.Services.PropertyMappingGenerator.Generate(EdmEntityType entityType, IEnumerable`1 properties, DbEntitySetMapping entitySetMapping, DbEntityTypeMappingFragment entityTypeMappingFragment, IList`1 propertyPath, Boolean createNewColumn)
at System.Data.Entity.ModelConfiguration.Edm.Services.EntityTypeMappingGenerator.Generate(EdmEntityType entityType, DbDatabaseMapping databaseMapping)
at System.Data.Entity.ModelConfiguration.Edm.Services.DatabaseMappingGenerator.GenerateEntityTypes(EdmModel model, DbDatabaseMapping databaseMapping)
at System.Data.Entity.ModelConfiguration.Edm.Services.DatabaseMappingGenerator.Generate(EdmModel model)
at System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.GenerateDatabaseMapping(EdmModel model, DbProviderManifest providerManifest)
at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.Initialize()
at System.Data.Entity.Internal.InternalContext.ForceOSpaceLoadingForKnownEntityTypes()
at System.Data.Entity.DbContext.System.Data.Entity.Infrastructure.IObjectContextAdapter.get_ObjectContext()
at Breeze.WebApi.EFContextProvider`1.GetCsdlFromObjectContext(Object context)
at Breeze.WebApi.EFContextProvider`1.GetCsdlFromDbContext(Object context)
at Breeze.WebApi.EFContextProvider`1.BuildJsonMetadata()
at Breeze.WebApi.ContextProvider.Metadata()
at DocCode.Controllers.NorthwindController.Metadata() in c:\Users\anwalker\Downloads\breeze-runtime-plus-0.78.2\Samples\DocCode\DocCode\Controllers\NorthwindController.cs:line 20
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.<ExecuteAsync>b__4()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)
InnerException:

TimeSpan support was added in build 0.84.1.
TimeSpans are represented as ISO 8601 'duration' strings on the breeze client. See http://en.wikipedia.org/wiki/ISO_8601
Full query support includes the ability to both filter and return TimeSpan/Duration properties. i.e.
var query = EntityQuery.from("Contracts").where("TimeElapsed", ">", "PT4H30M");

Ok, after a little research, it makes sense to serialize a .NET timespan to the javascript client using the ISO8601 'duration' standard which would represent a timespan in days, hours, minutes, and seconds as a formatted string something like: "PnnnDTnnHnnMnn.nnnS". Obviously, you will need a javascript library on the client to interpret and work with this. Would this meet your needs?
I've added this to our feature request log, but please also add it to the Breeze User Voice (and vote for it :)). This helps us prioritize the outstanding feature requests.

Hm.. The request makes sense. But what would you want it converted to in javascript, a string or a number of seconds since a point in time or .... Is there a standard javascript representation for a .NET timespan?

Related

Unable to determine the serialization information for "Expression"

I receive the error message Unable to determine the serialization information for a => a.CurrentProcessingStep when I try to Update my document.
I'm using the Mongo .NET Driver version 2.8 and .NET Framework 4.7.2.
I'm building the filter and update statements using the builder helpers from the library.
Here is the relevant section of my document class:
[BsonIgnoreExtraElements]
[DebuggerDisplay("{Term}, Rule Status = {_ruleStatus}, Current Step = {_currentProcessingStep}")]
public class SearchTermInfo : AMongoConnectedObject
{
[BsonElement("CurrentProcessingStep")]
private ProcessingStep _currentProcessingStep;
[BsonElement("RuleStatus")]
private RuleStatus _ruleStatus;
[BsonDateTimeOptions(Kind = DateTimeKind.Local)]
public DateTime AddDateTime { get; set; }
[BsonIgnore]
[JsonIgnore]
public ProcessingStep CurrentProcessingStep
{
get => _currentProcessingStep;
set => AddHistoryRecord(value);
}
[BsonIgnore]
[JsonIgnore]
public RuleStatus RuleStatus
{
get => _ruleStatus;
set => AddHistoryRecord(value);
}
I'm building the filter with this code:
FilterDefinition<SearchTermInfo> filter = Builders<SearchTermInfo>.Filter.And(
Builders<SearchTermInfo>.Filter.Eq(a => a.Id, recordId),
Builders<SearchTermInfo>.Filter.Or(
Builders<SearchTermInfo>.Filter.Eq(a => a.CurrentProcessingStep, currentStep),
Builders<SearchTermInfo>.Filter.Exists("CurrentProcessingStep", false)
)
);
Then I execute the update:
UpdateResult results =
searchTermInfoCollection.MongoCollection.UpdateOne(filter, update, null, cancellationToken);
and I get this error:
? ex
{"Unable to determine the serialization information for a => a.CurrentProcessingStep."}
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233079
HelpLink: null
InnerException: null
Message: "Unable to determine the serialization information for a => a.CurrentProcessingStep."
Source: "MongoDB.Driver"
StackTrace: " at MongoDB.Driver.ExpressionFieldDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, Boolean allowScalarValueForArrayField)
at MongoDB.Driver.SimpleFilterDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)\r\n
at MongoDB.Driver.OrFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)\r\n
at MongoDB.Driver.AndFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)\r\n
at MongoDB.Driver.MongoCollectionImpl`1.ConvertWriteModelToWriteRequest(WriteModel`1 model, Int32 index)\r\n
at System.Linq.Enumerable.<SelectIterator>d__5`2.MoveNext()\r\n
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)\r\n
at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation..ctor(CollectionNamespace collectionNamespace, IEnumerable`1 requests, MessageEncoderSettings messageEncoderSettings)\r\n
at MongoDB.Driver.MongoCollectionImpl`1.CreateBulkWriteOperation(IEnumerable`1 requests, BulkWriteOptions options)\r\n
at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IClientSessionHandle session, IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)\r\n
at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass23_0.<BulkWrite>b__0(IClientSessionHandle session)\r\n
at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken)\r\n
at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)\r\n
at MongoDB.Driver.MongoCollectionBase`1.UpdateOne(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, Func`3 bulkWrite)\r\n
at MongoDB.Driver.MongoCollectionBase`1.UpdateOne(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, CancellationToken cancellationToken)\r\n
at SaFileIngestion.FileProcessorEngine.LockRecord(Int64 recordId, ProcessingStep currentStep, CancellationToken cancellationToken)
in D:\\[File Path]\\SaFileIngestion\\FileProcessorEngine.cs:line 195"
TargetSite: {MongoDB.Driver.RenderedFieldDefinition`1[TField] Render(MongoDB.Bson.Serialization.IBsonSerializer`1[TDocument], MongoDB.Bson.Serialization.IBsonSerializerRegistry, Boolean)}
I've also tried to build the filter with this code:
Builders<SearchTermInfo>.Filter.Eq("CurrentProcessingStep", currentStep),
It was my impression that I should be able to build an expression using the property accessor, even though it is flagged as BsonIgnore, since the private field has been attributed with BsonElementAttribute with the same name as the ignored property accessor.
Any guidance provided is appreciated.
Thanks
I eventually resolved this. I don't remember the exact solution as it was over a year ago. I do remember there was something wrong with the way the query was being constructed.

How to solve entity framework core System.ArgumentNullException

From the following stacktrace, I can't tell what is wrong by the error message. I ran the migration command with --verbose flag hoping it would help pinpoint the issue but zilch.
dotnet ef migrations add migwl3 --verbose
I can't find a parameter named key
System.ArgumentNullException: Value cannot be null.
Parameter name: key
at Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T](T value, String parameterName)
at Microsoft.EntityFrameworkCore.SqlServerMetadataExtensions.SqlServer(IKey key)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer. <Add>d__41.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__35`1.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer. <Add>d__29.MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer. <DiffCollection>d__56`1.MoveNext()
at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.S ort(IEnumerable`1 operations, DiffContext diffContext)
at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.Scaf foldMigration(String migrationName, String rootNamespace, String subNamespace)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMig ration(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(S tring name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Exec ute(Action action)
Value cannot be null.
Parameter name: key
Any tips on how to zero in on the issue (the project compiles fine) would be greatly appreciated
This is one of the first results from searching for Microsoft.EntityFrameworkCore.Utilities.Check.NotNull, so I'll add my stupid mistake:
I refactored a class to a different DatabaseContext, and was then calling Join between two IQueryable queries from those different contexts-- Obviously you can't do that in EntityFramework
I think Your Problem is Your Model that you not decoration [Key] attribute Or
Not use HasKey.
please share your code.
make sure that you wrote the Interface name in the constructor not the repository name.
example program
private IReviewRepository _reviewRepository;
private IPokemonRepository _pokemonRepository;
private readonly IReviewerRepository _reviewerRepository;
private IMapper _mapper;
public ReviewController(IReviewRepository reviewRepository,
IMapper mapper,
IPokemonRepository pokemonRepository,
IReviewerRepository reviewerRepository)
{
_reviewRepository = reviewRepository;
_pokemonRepository = pokemonRepository;
_reviewerRepository = reviewerRepository;
_mapper = mapper;
}
ReviewRepository instead of IReviewRepository
ReviewerRepository instead of IReviewerRepository
PokemonRepository instead of IPokemonRepository

EF code first and Paging

we are using EF 6.1 and code first along with the Unit of work and repository pattern.
the confusion we are facing is that at many places its written that if we use Skip & Take on a Dbset, the paging is automatically handled.
but when we see the query being created, it does not contain any clause for paging.
kindly assist what is the possible case , the sample code is as follows:
public virtual IEnumerable<TEntity> GetSorted(Func<TEntity, Object> order,int skip, int take, params Expression<Func<TEntity, object>>[] includes)
{
IQueryable<TEntity> query = dbSet;
foreach (var include in includes)
{
query = dbSet.Include(include);
}
IEnumerable<TEntity> data = dbSet.OrderBy(order).Skip(skip).Take(take).ToList();
//IEnumerable<TEntity> data = query.OrderBy(order).Skip(skip).Take(take).ToList();
return data;
}
any help appreciated..
Your order parameter needs to be of Expression<Func<TEntity, TSortBy>> type in order to match the signature of Queryable.OrderBy(). When you're passing a delegate (Func<TEntity, Object>), the only OrderBy() overload that will match this argument is Enumerable.OrderBy() and not the Queryable.OrderBy() that you're expecting (both are extension-methods of course).
When the sorting is being done by Enumerable.OrderBy() (Linq-to-Objects), the query must be executed first (since Linq-to-Objects is meant for working with objects that are already in memory).
However, when Queryable.OrderBy() is invoked, the order-by expression is being passed to the Linq provider that is then capable of parsing and translating it to a store query (SQL in this case).
So, when you're passing Func<TEntity, Object> to OrderBy, you're getting IEnumerable<TEntity> in return, and further (chained) calls to Skip() and Take() are no longer intercepted by Linq-To-Entities.
This is how your method signature should look like:
public virtual IEnumerable<TEntity> GetSorted<TSortedBy>(Expression<Func<TEntity, TSortedBy>> order, int skip, int take, params Expression<Func<TEntity, object>>[] includes)
See MSDN

How to intercept a SELECT query

I am exploring Entity Framework 7 and I would like to know if there is a way to intercept a "SELECT" query. Every time an entity is created, updated or deleted I stamp the entity with the current date and time.
SELECT *
FROM MyTable
WHERE DeletedOn IS NOT NULL
I would like all my SELECT queries to exclude deleted data (see WHERE clause above). Is there a way to do that using Entity Framework 7?
I am not sure what your underlying infrastructure looks like and if you have any abstraction between your application and Entity Framework. Let's assume you are working with DbSet<T> you could write an extension method to exclude data that has been deleted.
public class BaseEntity
{
public DateTime? DeletedOn { get; set; }
}
public static class EfExtensions
{
public static IQueryable<T> ExcludeDeleted<T>(this IDbSet<T> dbSet)
where T : BaseEntity
{
return dbSet.Where(e => e.DeletedOn == null);
}
}
//Usage
context.Set<BaseEntity>().ExcludeDeleted().Where(...additional where clause).
I have somewhat same issue. I'm trying to intercept read queries like; select, where etc in order to look into the returned result set. In EF Core you don't have an equivalent to override SaveChanges for read queries, unfortunately.
You can however, still i Entity Framework Core, hook into commandExecuting and commandExecuted, by using
var listener = _context.GetService<DiagnosticSource>();
(listener as DiagnosticListener).SubscribeWithAdapter(new CommandListener());
and creating a class with following two methods
public class CommandListener
{
[DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting")]
public void OnCommandExecuting(DbCommand command, DbCommandMethod executeMethod, Guid commandId, Guid connectionId, bool async, DateTimeOffset startTime)
{
//do stuff.
}
[DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted")]
public void OnCommandExecuted(object result, bool async)
{
//do stuff.
}
}
However these are high lewel interceptors and hence you won't be able to view the returned result set (making it useless in your case).
I recommend two things, first go to and cast a vote on the implementation of "Hooks to intercept and modify queries on the fly at high and low level" at: https://data.uservoice.com/forums/72025-entity-framework-core-feature-suggestions/suggestions/1051569-hooks-to-intercept-and-modify-queries-on-the-fly-a
Second you can use PostSharp (a commercial product) by using interceptors like; LocationInterceptionAspect on properties or OnMethodBoundaryAspect for methods.

Enity Framework regular error while command executing

I am developing a WPF Applicaton using Entity Framework for data access. As design pattern i use "MVVM" for tier organization, and "Repository" with "UnitOfWork" for data layer organization.
Generic Repository class:
public class EFRepository : IRepository where T : class
{
public IUnitOfWork UnitOfWork { get; set; }
private IObjectSet _objectset;
private IObjectSet ObjectSet
{
get
{
if (_objectset == null)
{
_objectset = UnitOfWork.Context.CreateObjectSet();
}
return _objectset;
}
}
public virtual IQueryable All()
{
return ObjectSet.AsQueryable();
}
...
Unit of work interface:
public interface IUnitOfWork: IDisposable
{
ObjectContext Context { get; set; }
void Save();
bool LazyLoadingEnabled { get; set; }
bool ProxyCreationEnabled { get; set; }
string ConnectionString { get; set; }
}
I build all L2E queries in model layer, like:
this.repository1.All().First(i => i.Field1 == some_value);
Sometimes here is thrown an EntityCommandExecutionException. It happens sometimes, but not regular. There is no rule to make this exception occur.
Exception Detail:
EntityCommandExecutionException:
{"An error occurred while executing the command definition. See the inner exception for details."}
InnerException:
{"Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding."}
StackTrace:
at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable.GetEnumerator()
at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
at System.Data.Objects.ELinq.ObjectQueryProvider.b__0[TResult](IEnumerable`1 sequence)
at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.First[TSource](IQueryable`1 source, Expression`1 predicate)
Please, help me to find out the problem, i really don`t know what to do now =(
p.s.:
I tried to provoke this error building and executing L2E queries in simple Console Application. I tried single L2E queries and through 1000-iterations cycles. But nothing caused this exception.
I can post any additional information if needed.
[23.03.2011]
Additional Info:
Entity Framework 4.0
MSSQL Server 2008
this exception can be thrown any time the query take place. It can be l2e query to small table (<200 rows) or large (>500k rows). Also this exception can be caused by Function Import call
when this exception is thrown,
{"Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding."}
it is thrown immediately, but the connection timeout is set to 30 seconds! (i think that is "key feature")
DB Server is situated in LAN, and there is no heavy traffic on DB.
as i have found out, this exception can occur any time no matter what kind of queries or tables are used.
I dont use transaction. This error occur even if i use only select queries.
I think the problem caused by using WPF with EF, because my "EF part" works fine in Console Application.
The ObjectContext has two timeout parameters:
int x = myObjectContext.Connection.ConnectionTimeout;
and
int? x = myObjectContext.CommandTimeout;
Looking at the exception and callstack I don't think that the ConnectionTimeout is the problem (that's the maximum time to try to establish a connection from the client to SQL Server). You could try to set the CommandTimeout to some high value (that's the timeout for queries and commits with SaveChanges; the value null means that the default of the underlying provider will be taken).