breeze / breeze.server.net Goto Github PK
View Code? Open in Web Editor NEWBreeze support for .NET servers
License: MIT License
Breeze support for .NET servers
License: MIT License
Ef core 2.0 has more feature is getting closser to EF6
its about time to add EFCore version
Is there any possibility to execute breeze.js "remote linq" queries over the Remote.Linq implementation ( http://remotelinq.codeplex.com/ , http://remotelinq.codeplex.com/discussions/585979) ?
There doesn't seem to be any documentation on using Breeze with .Net Core outwith the github issues. I have managed to coax it into life by inspecting efforts by others. I appreciate that it's yet to make v1.0 but there are some significant changes and little guidance as to how to use in a .Net Core app.
Is there any way to pull out a property of a collection with a $select query? I'd love to be able to pull out just one property from a collection, but it doesn't appear to be possible, instead, I get an error like:
Unable to locate property 'personRolesId' on type 'System.Collections.Generic.List
1[PersonRoleVo]`
Reference:
We use breeze with NHibernate and Oracle.
As recommended in the doc, we set TransactionType
to TransactionType.DbTransaction
.
We set enlist=true
in the connectionstring.
But now, we also use NServicebus. In order to have both msmq and db in the same transaction, we changed TransactionType
to TransactionType.TransactionScope
.
Out of the box, it didn't work throwing this exceptionConnection is already part of a local or a distributed transaction
.
To make it work, I removed the code related to transaction inside NHContext
. I don't know exactly what it was supposed to do, as this code is already part of the transaction started in the The code is still needed if no TransactionSettings is set(None).ContextProvider
.
Now it works, with both types of Transactions.
Do you see any issues with that?
NB: setting enlist=dynamic seems to work with the initial code. BUT, if an exception occurs the data are not rollbacked. Looking at Oracle docs, dynamic means you have to enlist the transaction by yourself. So it's not the solution
NB2: The changes works well... but we're also using envers and it works only with Oracle and not with Sql Server
NB3: The issue spans over breeze and nhibernate... I'll try to see with NHibernate people what's the best solution
Is there anyway to apply the user query in the controller in order to perform some actions to the final result set?
Take the following example:
[HttpGet]
public IQueryable<Container> Containers(bool populate)
{
var containers = _contextProvider.Context.Containers;
if (populate)
{
foreach (var container in containers)
{
container.Populate(_contextProvider.Context);
}
}
return containers;
}
The problem here is that I am doing this Populate()
action to all records in this table instead of just the ones that the user requested because their query has not been applied yet. How can I achieve this?
Please see StackOverflow question here.
Hi thanks for all the work on breeze, I've used it on so many projects alongside .net full framework.
Now, I'm starting on some rather large greenfield projects, and noticed that activity has died down considerably on stackoverflow, and updates to breeze library in general (temphire demo app, etc.)
This could very well be because breezejs is now considered mature and stable and doesn't need a lot of fixes because everything pretty much works very reliably.
I just would like to know before beginning these new projects...would breeze still be the go-to recommended project for greenfield these days, or is it winding down because breeze developers (users and/or contributors) are moving to other things, like graphql?
Again, thanks for all the work over the years this project has been a game-changer for my past projects.
Are there any plans to migrate to ASP.NET 5 and EF7 (vNext) in the future?
Thanks for such fantastic software.
Apologies if this is not possible or represents a really bad idea from an architecture point of view. I would like to quickly and easily be able to map from a Dto to the corresponding server-model object before saving. It is worth noting the example projects referenced in the help documentation and hosted on GitHub demonstrates mapping objects to the DTO, but mapping back is marked as Todo: transform entities in saveBundle from DTO form into server-model form.
.
The easiest way I can see to do this (glancing at the relevant code) would be something like (untested code):
class MyContextProvider : EFContextProvider<MyDbContext>
{
protected override EntityInfo CreateEntityInfoFromJson(JTokenReader tokenReader, Type entityType)
{
var entityInfo = base.CreateEntityInfoFromJson(tokenReader, entityType);
entityInfo.Entity= MapFromDto(entityInfo.Entity);
return entityInfo;
}
private static object MapFromDto(object obj)
{
Type t = obj.GetType();
if (t == typeof(DtoCustomer))
{
DtoCustomer customer = (DtoCustomer)entityInfo;
return new DatabaseCustomer { Id = customer.Id .... };
}
return obj;
}
}
In order to do things this way, it would be necessary for the ContextProvider.CreateEntityInfoFromJson method:
protected internal EntityInfo CreateEntityInfoFromJson(dynamic jo, Type entityType) {
return CreateEntityInfoFromJson(new JTokenReader(jo), entityType);
}
protected internal virtual EntityInfo CreateEntityInfoFromJson(JTokenReader reader, Type entityType) {
Is this an appropriate change to make? Are there better suggestions?
Thank you.
This issue is related to this issue on SO:
http://stackoverflow.com/questions/16651889/entity-deleted-on-the-server-will-remain-unchanged-on-the-client-default-breeze
In my applicaiton, I add entities (marked "Deleted") to the saveMap in BeforeSaveEntities on the server. They get deleted on the server, but are returned to the client with no indication that they have been deleted. The client therefore has no chance of knowing that a server-deleted entity should be removed from the client cache.
Is there any way to inform the client that an entity has been deleted on the server (in BeforeSaveEntities)?
I've got EF Model and ContextProvider
:
public class VObjectLabel
{
[Key]
public int Id { get; set; }
public virtual VObject VObject { get; set; }
public string VObjectID { get; set; }
}
public class VObject
{
public VObject()
{
SecurityLevelID = 1;
}
[Key]
public string Id { get; set; }
}
public partial class DB : DbContext
{
public DbSet<VObject> VObjects { get; set; }
public DbSet<VObjectLabel> VObjectLabels { get; set; }
}
public class DBModelContextProvider : EFContextProvider<DB>
{
protected override void AfterSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap, List<KeyMapping> keyMappings)
{
base.AfterSaveEntities(saveMap, keyMappings);
}
protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap)
{
return base.BeforeSaveEntities(saveMap);
}
}
When i delete something from this contextprovider like this, passing VObjectLabel
with the Id
and VObjectID
filled.
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
BeforeSaveEntities
have saveMap
with Id
and VObjectID
filled,
AfterSaveEntities
have saveMap
with Id
filled but VObjectID
is empty .
When i change VObject
key to int, it is working as expexted, key is in After and Before hooks.
There is in issue with arrays In the JsonToDictionary method of ContextProvider.cs. They are not taken into account.
For instances, I have a property which is a list of strings, when modifying it on the client and than saving it by calling saveChanges, The associated deserialized originalValuesMap's value is null.
Here is my fix:
private Dictionary<String, Object> JsonToDictionary(dynamic json) {
if (json == null) return null;
var jprops = ((System.Collections.IEnumerable)json).Cast<JProperty>();
var dict = jprops.ToDictionary(jprop => jprop.Name, jprop => {
var val = jprop.Value as JValue;
if (val != null) {
return val.Value;
}
else if (jprop.Value as JArray != null){
return jprop.Value as JArray;
}
else{
return jprop.Value as JObject;
}
});
return dict;
}
Thanks
I get this error when trying to add Breeze.Server.AspNetCore.NetFramework package to ASP.Net Core 2.0 project target full .Net Framework 4.6.1:
Project is targeting runtime 'win7-x86' but did not resolve any runtime-specific packages for the 'Microsoft.NETCore.App' package. This runtime may not be supported by .NET Core.
Hello,
Suppose I have the following (simplified) Entity model:
public class Invoice
{
public int Id { get; set }
public int CustomerId { get; set; } <= not nullable
public int? CategorieId { get; set; } <= nullable!
public virtual Customer Customer
public virtual Category Category
//much more properties...
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set }
}
public class InvoiceType
{
public int Id { get; set; }
public string Title{ get; set }
}
When I query this with Breeze server and Breeze Javascript client like this:
let q = new breeze.EntityQuery()
.from('Invoices')
.select('Customer.Name')
it works perfectly alright.
However, when I select a nullable column/property, e.g.
let q = new breeze.EntityQuery()
.from('Invoices')
.select('Category.Title')
and hit a row without an InvoiceType a server error occurs:
System.InvalidOperationException: The cast to value type 'InvoiceType' failed
because the materialized value is null. Either the result type's generic parameter or
the query must use a nullable type.
I can reproduce this behaviour in a Linqpad query: Invoices.Select(x => new { x.Id, x.InvoiceType .Title })
will result in an error for rows without InvoiceType.
However, in Linqpad I can easily fix this: Invoices.Select(x => new { x.Id, Title = x.InvoiceType == null ? null : x.InvoiceType.Title })
I can't do this on the client...
Is this some kind of edge case, or a bug maybe?
I'm using the Core version of Breeze server.
I am using the following libraries in my Project
Breeze.Angular.1.1.1
Breeze.Angular.Directives.1.3.10
Breeze.Client.1.5.5
Breeze.Server.ContextProvider.1.5.0
Breeze.Server.ContextProvider.1.6.0
Breeze.Server.ContextProvider.EF6.1.5.0
Breeze.Server.ContextProvider.EF6.1.6.0
Breeze.Server.WebApi2.1.6.0
what's the equivalent libraries for .Net Core for the above that I am using in .Net Framework 4.7.1
For .net it would be really great to an a typescript adapter on the server that creates .d.ts files and places them in a folder of your choice. (Development mode only of course)
So it happens like a the metadata but the the adapter would write the definition to a files to a path of your choice
I did this thing to write out metadata so i could cache it.
But a similar thing could be done with the .d.ts files.
internal static void WriteContextMetadata<CONTROLLER>(string name) where CONTROLLER : IMetaController, new()
{
var metadata = new CONTROLLER().Metadata();
// construct the filename and runtime file location
var fileName = HostingEnvironment.MapPath("~/meta/" + name + "Metadata.js");
// the same pre- and post-fix strings we used earlier
string prefix = "window." + name + "BreezeMetadata = JSON.stringify(";
const string postfix = ");";
// write to file
using (var writer = new StreamWriter(fileName))
{
writer.WriteLine(prefix + metadata + postfix);
}
}
But have the actual types would be stupefyingly awesome.
Hello,
I have faced a problem when using breeze.sharp and breeze.server.net - Asp.Net Core + EF Core.
Everything works well when query the full list (http://localhost:5678/breeze/share/companies).
But when I add parameter (http://localhost:5678/breeze/share/companies?$filter=TagName%20eq%20%27DHL%27)
I get error:
{"$id":"32","$type":"Breeze.AspNetCore.ErrorDto, Breeze.AspNetCore.NetCore","Code":0,"Message":"This EntityQuery ctor requires a valid json string. The following is not json: $filter=TagName eq 'DHL'","StackTrace":" at Breeze.Core.EntityQuery..ctor(String json) in D:\GitHub\Breeze\breeze.server.net\AspNetCore\Breeze.Core\Query\EntityQuery.cs:line 37\r\n at Breeze.AspNetCore.BreezeQueryFilterAttribute.OnActionExecuted(ActionExecutedContext context) in D:\GitHub\Breeze\breeze.server.net\AspNetCore\Breeze.AspNetCore.NetCore\QueryFilter.cs:line 33\r\n at Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)\r\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()\r\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)\r\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()","EntityErrors":null}
Try to debug deeper the source code of breeze.server.net and found the error happens in file JsonHelper.cs at line 12........... JToken.parse(json).....
Unable to create the JToken from the query string.
Please help....
Trying to SaveChanges of a single enum property value update throws System.Data.Entity.Infrastructure.DbUpdateConcurrencyException.
The enum property is defined like this:
public virtual System.Nullable<StanZleceniaOplaty> Stan { get; set; }
public enum StanZleceniaOplaty : int
{
Created,
Started,
Canceled,
Rejected,
Paid
}
EntityTypeConfiguration for entity ZlecenieOplaty configures Stan with the following code:
this
.Property(p => p.Stan)
.IsConcurrencyToken()
.HasColumnType("int");
I can see that the SQL generated by EFContextProvider agains the EF 6.1 DB is wrong ([Stan] is not changed, because @0 == @2, @2 has wrong value - should be 0).
exec sp_executesql N'UPDATE [dbo].[ZlecenieOplaty]
SET [Stan] = @0
WHERE (([Id] = @1) AND ([Stan] = @2))
SELECT [NrZlecenia]
FROM [dbo].[ZlecenieOplaty]
WHERE @@ROWCOUNT > 0 AND [Id] = @1',
N'@0 int,@1 int,@2 int',
@0=2,
@1=3,
@2=2
In effect the following exception is thrown.
System.Data.Entity.Infrastructure.DbUpdateConcurrencyException occurred
HResult=-2146233087
Message=Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
Source=EntityFramework
StackTrace:
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at Alcance.Entities.AlcanceDbContext.SaveChanges() in d:\Develop\alcance\src\dev\Alcance.Data\Model\AlcanceModel.AlcanceDbContext.Connection.cs:line 121
InnerException: System.Data.Entity.Core.OptimisticConcurrencyException
HResult=-2146233087
Message=Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
Source=EntityFramework
StackTrace:
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 rowsAffected, UpdateCommand source)
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
at System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
InnerException:
When using inlineCount method NH profiler shows that actually 2 count queries are being made
take a look at the screen shots
this may result in bad performance.
I also talked to @steveschmitt about this issue
When you are doing a select projection, the serialized Json has a long $type
property. For example:
"$type":"_IB_w3cYOcY0lxw2mLrFH_pc88Gzr_dks[[System.Guid, mscorlib]], _IB_w3cYOcY0lxw2mLrFH_pc88Gzr_dks_IdeaBlade"
For large collections, this adds a large overhead to the call, especially when you are only pulling one or two properties off of the objects. It would be much nicer to use TypeNameHandling = None
for DynamicTypes
. Even better would be to somehow put the $type
on the array if all items have the same type.
In the latest NuGet package Breeze.Server.ContextProvider (1.6.6), in the method Breeze.ContextProvider.BreezeConfig.CreateJsonSerializerSettings(), the format string currently used for the IsoDateTimeConverter will cause DateTime and DateTimeOffset values to serialize differently with different "Accept-Language" request header values to BreezeControllers:
jsonSerializerSettings.Converters.Add(new IsoDateTimeConverter {
DateTimeFormat = "yyyy-MM-dd\\THH:mm:ss.fffK"
// DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"
});
Different cultures use different separator characters between year/month/day and hours/minutes/seconds.
The problem with the format string in your code is that the IsoDateTimeConverter interprets dash and colon characters as special placeholder symbols to be replaced with the locale specific separators. Locale seems to be decided by the "Accept-Language" request header (not by Thread.CurrentThread.CurrentCulture which I believed to be the case initially, since ASP.NET by default automatically sets this by parsing the "Accept-Language" request header).
If you test an ASP.NET WebApi2 Breeze Controller with a browser where language is set to f.ex. "Norwegian bokmรฅl", the "Accept-Language" request headers will be "nb-NO", and all dates in the JSON data returned from the controller will be wrong, culture relative, non-ISO-8601-compliant, since the hours/minutes/seconds separator for Norway is '.' (notice the period character used as time separator):
2018-02-21T17.05.00.000+00:00
To use non-culture-relative separators in the IsoDateTimeConverter format string, you need to put single-quotes around them.
The correct format for ISO-8601 date format (with only 3 second fraction digits to support IE9) should be:
"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFK"
Please fix this as soon as possible and release a new version of the NuGet package - this is a current production issue in our product. We have found a temporary workaround, but this is clearly a bug on your end.
When we add an SP which returns some columns, i.e. in EF model its return type is represented with a Complex Type, EFContextProvider.Metadata() throws exception:
System.ArgumentException: 'Could not find the CLR type for 'Model.PendingCallListGet_Result'.'
Stack trace:
at System.Data.Entity.Core.Metadata.Edm.MetadataWorkspace.GetObjectSpaceType[T](T edmSpaceType)
at System.Data.Entity.Core.Metadata.Edm.MetadataWorkspace.GetObjectSpaceType(StructuralType edmSpaceType)
at Breeze.ContextProvider.EF6.EFContextProvider1.<>c__DisplayClass56_0.<UpdateCSpaceOSpaceMappingCore>b__1(StructuralType st) in C:\\git\\Breeze\\breeze.server.net\\AspNet\\Breeze.ContextProvider.EF6\\EFContextProvider.cs:line 727 at System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoveNext()\r\n at System.Collections.Generic.List1..ctor(IEnumerable
1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Breeze.ContextProvider.EF6.EFContextProvider
1.UpdateCSpaceOSpaceMappingCore(XDocument xDoc, MetadataWorkspace metadataWs) in C:\git\Breeze\breeze.server.net\AspNet\Breeze.ContextProvider.EF6\EFContextProvider.cs:line 724
at Breeze.ContextProvider.EF6.EFContextProvider1.UpdateCSpaceOSpaceMapping(XDocument xDoc, ObjectContext oc) in C:\\git\\Breeze\\breeze.server.net\\AspNet\\Breeze.ContextProvider.EF6\\EFContextProvider.cs:line 697 at Breeze.ContextProvider.EF6.EFContextProvider
1.GetMetadataFromObjectContext(Object context) in C:\git\Breeze\breeze.server.net\AspNet\Breeze.ContextProvider.EF6\EFContextProvider.cs:line 614
at Breeze.ContextProvider.EF6.EFContextProvider1.GetMetadataFromDbContext(Object context) in C:\\git\\Breeze\\breeze.server.net\\AspNet\\Breeze.ContextProvider.EF6\\EFContextProvider.cs:line 593 at Breeze.ContextProvider.EF6.EFContextProvider
1.GetMetadataFromContext(Object context) in C:\git\Breeze\breeze.server.net\AspNet\Breeze.ContextProvider.EF6\EFContextProvider.cs:line 575
at Breeze.ContextProvider.EF6.EFContextProvider`1.BuildJsonMetadata() in C:\git\Breeze\breeze.server.net\AspNet\Breeze.ContextProvider.EF6\EFContextProvider.cs:line 142
at Breeze.ContextProvider.ContextProvider.Metadata() in C:\git\Breeze\breeze.server.net\AspNet\Breeze.ContextProvider\ContextProvider.cs:line 34
I am finally getting around to using the EnableBreezeQuery as described in #12, but I'm having an issue.
I've set the options to disable expand, so as expected, if I call: orders?$expand=privateObject
, I'll get the expected error:
{
"$id":"1",
"$type":"System.Web.Http.HttpError, System.Web.Http",
"Message":"The query specified in the URI is not valid. Query option 'Expand' is not allowed. To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings.",
"ExceptionMessage":"Query option 'Expand' is not allowed. To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings.",
"ExceptionType":"Microsoft.Data.OData.ODataException",
"StackTrace":" at System.Web.Http.OData.Query.Validators.ODataQueryValidator.ValidateQueryOptionAllowed(AllowedQueryOptions queryOption, AllowedQueryOptions allowed)\r\n at System.Web.Http.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n at System.Web.Http.OData.EnableQueryAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)\r\n at Breeze.WebApi2.EnableBreezeQueryAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)\r\n at System.Web.Http.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)\r\n at System.Web.Http.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)"
}
However, if I just call: orders?$select=privateObject
, the privateObject will be returned. It looks like you can by pass the expand restriction by just use $select
It would be extremely helpful to get a list of steps to get an ASP.Net Core Breeze server up, even if a full sample is a bit further away.
BTW, this maybe just me, but sometimes a series of step-by-step instructions are far more instructive than code samples...I found Brian Noyes' Pluralsight video far more helpful than the temphire sample.
Message=DateTimeOffsetConverter cannot convert from System.DateTime.
Source=System
StackTrace:
at System.ComponentModel.TypeConverter.GetConvertFromException(Object value)
at System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at System.ComponentModel.DateTimeOffsetConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at Breeze.ContextProvider.EF6.EFContextProvider`1.ConvertValue(Object val, Type toType)
at Breeze.ContextProvider.EF6.EFContextProvider`1.SetPropertyValue(Object entity, String propertyName, Object value)
at Breeze.ContextProvider.EF6.EFContextProvider`1.RestoreOriginal(EntityInfo entityInfo)
at Breeze.ContextProvider.EF6.EFContextProvider`1.<ProcessAllDeleted>b__9(EFEntityInfo entityInfo)
at System.Collections.Generic.List`1.ForEach(Action`1 action)
at Breeze.ContextProvider.EF6.EFContextProvider`1.ProcessAllDeleted(List`1 deletedEntities)
at Breeze.ContextProvider.EF6.EFContextProvider`1.SaveChangesCore(SaveWorkState saveWorkState)
at Breeze.ContextProvider.ContextProvider.OpenAndSave(SaveWorkState saveWorkState)
at Breeze.ContextProvider.ContextProvider.SaveChanges(JObject saveBundle, TransactionSettings transactionSettings)
at WaterTrack.WebApi.Breeze.Controllers.BreezeController.SaveChanges(JObject saveBundle) in ...
This error occurs when trying to save changes to an entity that has a DateTimeOffset property and the entityInfo.OriginalValuesMap contains a value for that column. It seems that the when the OriginalValuesMap is parsed into a KVP, a DateTime instead of DateTimeOffset type is used for the value of the column.
Has anyone else run into this?
I followed the instructions from:
http://breeze.github.io/doc-js/metadata-with-ef.html
One thing I noticed is that the called to Metadata() hangs for 15 seconds (connection timeout) and then returns the data. I put in a fake connection string with a command timeout of 1 and it only hangs for about 1.6 seconds. Since I wrapped all this in a static, I only incur this penalty the first time.
I guess it probably isn't really a Breeze bug. I'm guessing it is more about the DbContext. Maybe there is something that can be done, maybe not?
I am using the .NET Core version with EF 6
Hi,
Quick FYI, the current NuGet package for ASP.NET Breeze.ContextProvider (ver 1.6.5) didnโt get updated to denote that version 9.0 of Newtonsoft.Json is now required. It still has the dependency metadata set to >= 6.0 .
Breeze/Breeze.WebApi/BreezeConfig.cs
sets NullValueHandling
to Include
; however, the ASP.NET Web API controller documentation says by default the formatter suppresses null values.
Is it known to be in a broken state or is something wrong on my end? I've fixed it by upgrading some dependencies, removing and adding some Microsoft refs. there is a project missing in one of the solutions.
More of heads up - as of yesterday, there are now concrete steps in the form of a alpha release for supporting OData on top of ASP.Net Core.
See this comment OData/WebApi#229 (comment)
It would be good to get this on the roadmap for Breeze as part of the ASP.Net core support you are adding.
In ContextProvider, Before Save Adding Entity into the SaveMap when none in the list. Specifically when BeforeSaveEntity returns false because it's performed it's own save and the aftersave will update the SaveMap returned to the client.
Added " if (entityInfos.Count > 0) " in the below block.
public void BeforeSave() {
SaveMap = new Dictionary<Type, List<EntityInfo>>();
EntitiesWithAutoGeneratedKeys = new List<EntityInfo>();
EntityInfoGroups.ForEach(eg => {
var entityInfos = eg.EntityInfos.Where(ei => ContextProvider.BeforeSaveEntity(ei)).ToList();
EntitiesWithAutoGeneratedKeys.AddRange(entityInfos.Where(ei => ei.AutoGeneratedKey != null));
if (entityInfos.Count > 0) // <-----ADDED
SaveMap.Add(eg.EntityType, entityInfos);
});
SaveMap = ContextProvider.BeforeSaveEntities(SaveMap);
}
In EF6 ContextProvider, GetEntitySetName(entityType) should be inside the foreach.
Having issues passing back custom DTO's that I will provide my own SaveMap for so the js client's compare can satisfy HasChanges. (The above fix, masks this issue, because the Zero Count list is no longer in the Dictionary, but there is no point to look up types for empty lists )
Moved "GetEntitySetName(..." inside foreach
private List<EFEntityInfo> ProcessSaves(Dictionary<Type, List<EntityInfo>> saveMap) {
var deletedEntities = new List<EFEntityInfo>();
foreach (var kvp in saveMap) {
var entityType = kvp.Key;
foreach (EFEntityInfo entityInfo in kvp.Value) {
var entitySetName = GetEntitySetName(entityType); // <- Moved inside foreach
// entityInfo.EFContextProvider = this; may be needed eventually.
entityInfo.EntitySetName = entitySetName;
ProcessEntity(entityInfo);
if (entityInfo.EntityState == BreezeCp.EntityState.Deleted) {
deletedEntities.Add(entityInfo);
}
}
}
return deletedEntities;
}
Hope both the above work their way back into the codebase, trying to avoid forking
Thanks, and Great Work!
Mike
There's an issue with QueryFilter when it tries to decode a query string with inner contents containing an ampersand (&), e.g.
?{"where":{"CompanyName":{"contains":"Bob&Larry's Garage"}}}?anotherParameter=1
The ExtractAndDecodeQueryString method in QueryFns finds the first instance of an '&' in the query string and cuts off everything after that first instance, which I assume is to remove any additional parameters, such as 'anotherParameter' above. However, given the example above, it returns:
?{"where":{"CompanyName":{"contains":"Bob
QueryFilter blows up a few lines later when it passes this string to the EntityQuery constructor, which tries to deserialize the above as json.
Also, escaping the '&' doesn't really get us anywhere as there's no place where it is un-escaped.
Hi,
Suppose I have the following model:
public class User{
public string Name {get;set;}
public int? ImageId {get;set}
public Image Image {get;set;}
}
and
public class Image {
public string Url {get;set;}
}
On the client side, create a new image entity, assign it to a user entity, delete the image then save changes results in the following:
User.ImageId
is still pointing to the image which was deleted. A negative FK [Not Expected]The save results in a server error as User.ImageId
is pointing to a non existing entity.
Any help on this wold be greatly appreciated. Using AspNetCore 0.1.2 and ASP.NET Core 2.1.
Whey trying to query with 'expand' I keep getting a version of the following with all entities. For example:
https://localhost:44382/breeze/Accounts?{%22expand%22%3A[%22users%22]}
Error > SyntaxError: JSON.parse: end of data after property value in object at line 1 column 137 of the JSON data
Raw Data > {"results":[{"id":1,"customers":[],"guid":"1601a615-3b57-4f71-a0ff-f060b8467565","name":"OC SCUBA Center","users":[{"id":1,"accountId":1
Here are the entity models for reference:
public class AccountEntity
{
[Key]
public int id { get; set; }
public List<CustomerEntity> customers { get; set; } = new List<CustomerEntity>();
public Guid guid { get; set; } = Guid.NewGuid();
[Required]
[MaxLength(50)]
public string name { get; set; }
public List<UserEntity> users { get; set; } = new List<UserEntity>();
public List<WorkOrderEntity> workOrders { get; set; } = new List<WorkOrderEntity>();
}
public class UserEntity
{
[Key]
public int id { get; set; }
public int accountId { get; set; }
public AccountEntity account { get; set; }
[Required]
public string firstName { get; set; }
public Guid guid { get; set; } = Guid.NewGuid();
[Required]
public string lastName { get; set; }
[Required]
public string phone { get; set; }
[Required]
public string email { get; set; }
public List<WorkOrderItemLogEntity> workOrderItemLogs { get; set; } = new List<WorkOrderItemLogEntity>();
}
Breeze.ContextProvider.NH:
The following NHibernate mapping throws an NHibernate.AssertionFailure "Not an association":
set name="Zugnummern"
table="USER_ZUGNUMMER_T"
lazy="true"
cascade="save-update"
key column="USER_ID"
element column="TRAIN_NO"
type="string"
length="6"
not-null="true"
unique="false"
I made a proposal for a fix in NHMetadataBuilder.MakeAssociationProperty of project Breeze.ContextProvider.NH.
Dear breeze folks,
The beautiful breeze technology seems to be losing some momentum, but I think it can still add great value in this age of browser oriented application development. A vital step for survival is certainly support for the new .NET Core stack.
Since Entity Framework Core is not yet complete, any serious application needs EF6 anyway. So for starters we might as well use a Core web application targeting the Full Framework.
When I try to add Breeze, a number of things work, some do not. This is what I tried:
Override the default context provider to create the DbContext with a connectionstring (should be placed in setting later on)
public class EfContextProvider : EFContextProvider<MyDbContext>
{
protected override MyDbContext CreateContext()
{
return new MyDbContext("connection string");
}
}
In Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// other services ommited
services.AddScoped<EfContextProvider>(_ => new EfContextProvider());
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// other middleware ommitted
app.UseMvc(routes =>
{
routes.MapRoute("BreezeApi", "breeze/{controller}/{action}");
});
}
In project.json
{
"dependencies": {
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"EntityFramework": "6.1.3",
"Breeze.Server.WebApi2": "1.5.5",
"Breeze.Server.ContextProvider.EF6": "1.5.5"
},
"frameworks": {
"net452": {
"dependencies": {
"project containing dbcontext": {
"target": "project"
}
}
}
},
//other sections omitted
}
Finally a Breeze controller
[BreezeController]
public class BreezeController : Controller
{
EfContextProvider contextprovider;
public BreezeController(EfContextProvider contextprovider)
{
this.contextprovider = contextprovider;
}
[HttpGet]
public string Metadata()
{
return contextprovider.Metadata();
}
[HttpGet]
[EnableBreezeQuery]
public IQueryable<Person> Persons()
{
return contextprovider.Context.Persons;
}
}
The metadata is produced OK, and /breeze/persons produces json with Persons.
The problem is that all of the query string parameters like $filter
, $top
etc seem to be ignored. It seems as something goes wrong with the translation to the Odata layer.
Maybe this just a dead end and I should wait for the final porting, but I have the impression that is can fixed quite easy?
i am using aspnet core over EF6
the breeze api affect all return values my other webapi with $type and $id
I am attempting to implement something similar, but simpler, to NorthWind DTO example under the breeze.js.samples repo.
I can add and update my EF entities by way of my DTO objects without error. If I delete one however, I get the error.
System.ArgumentException: EntitySet not found for type MyApp.Web.Models.Tile ---> System.InvalidOperationException: Sequence contains no matching element
at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
at Breeze.Persistence.EF6.EFPersistenceManager`1.GetEntitySetName(Type entityType)
at Breeze.Persistence.EF6.EFPersistenceManager`1.GetKeyValues(Object entity)
--- End of inner exception stack trace ---
at Breeze.Persistence.EF6.EFPersistenceManager`1.GetKeyValues(Object entity)
at Breeze.Persistence.EF6.EFPersistenceManager`1.GetKeyValues(EntityInfo entityInfo)
at Breeze.Persistence.SaveWorkState.<ToSaveResult>b__20_5(EntityInfo entityInfo)
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Linq.Enumerable.<SelectManyIterator>d__16`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Breeze.Persistence.SaveWorkState.ToSaveResult()
at Breeze.Persistence.PersistenceManager.SaveChanges(JObject saveBundle, TransactionSettings transactionSettings)
at MyApp.Web.Controllers.ProfileController.SaveChanges(JObject req)
at lambda_method(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()
I am hooking into BeforeSaveEntities and AfterSaveEntities and using Automapper. I can see the Sql generated executes fine. It has something to do with turning the response into valid response for SaveChanges.
Not sure why an insert and update would function, but a delete wouldn't.
public SaveResult SaveChanges([FromBody]JObject req)
{
if (UserID != null)
{
_manager.BeforeSaveEntitiesDelegate += BeforeSaveEntities;
_manager.AfterSaveEntitiesDelegate += AfterSaveEntities;
var results = _manager.SaveChanges(req);
return results;
}
return null;
}
private static readonly List<(Type ClientType, Type ServerType)> _dtoMap = new List<(Type, Type)>
{
( typeof(Web.Models.Tile), typeof(Data.Models.Tile) )
};
private Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap)
{
foreach (var item in _dtoMap)
{
if (saveMap.TryGetValue(item.ClientType, out List<EntityInfo> clientGroup))
{
// We don't persist client entities
saveMap.Remove(item.ClientType);
if (saveMap.TryGetValue(item.ServerType, out List<EntityInfo> serverGroup) == false)
saveMap[item.ServerType] = serverGroup = new List<EntityInfo>();
foreach (var clientEntityInfo in clientGroup)
{
var serverEntity = _mapper.Map(clientEntityInfo.Entity, item.ClientType, item.ServerType);
var serverEntityInfo = _manager.CreateEntityInfo(serverEntity, clientEntityInfo.EntityState);
if (clientEntityInfo.AutoGeneratedKey != null)
{
// Potential optmization: Cache this somewhere, or define it, or even create some sort of interface
// on the client dto. I was thinking cache so we don't dirty up the dto...more.
var map = _mapper.ConfigurationProvider.FindTypeMapFor(item.ClientType, item.ServerType);
var prop = map.GetPropertyMaps().First(pm => pm.SourceMember == item.ClientType.GetProperty(clientEntityInfo.AutoGeneratedKey.PropertyName));
clientEntityInfo.AutoGeneratedKey.PropertyName = prop.DestinationProperty.Name;
clientEntityInfo.AutoGeneratedKey.Entity = serverEntity;
}
serverEntityInfo.UnmappedValuesMap = clientEntityInfo.UnmappedValuesMap;
serverEntityInfo.OriginalValuesMap = clientEntityInfo.OriginalValuesMap;
serverEntityInfo.AutoGeneratedKey = clientEntityInfo.AutoGeneratedKey;
serverEntityInfo.ForceUpdate = clientEntityInfo.ForceUpdate;
serverGroup.Add(serverEntityInfo);
}
}
}
return saveMap;
}
private void AfterSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap, List<KeyMapping> keyMappings)
{
foreach (var item in _dtoMap)
{
if (saveMap.TryGetValue(item.ServerType, out List<EntityInfo> serverGroup))
{
// We don't persist client entities
saveMap.Remove(item.ServerType);
if (saveMap.TryGetValue(item.ClientType, out List<EntityInfo> clientGroup) == false)
saveMap[item.ClientType] = clientGroup = new List<EntityInfo>();
foreach (var serverEntityInfo in serverGroup)
{
var clientEntity = _mapper.Map(serverEntityInfo.Entity, item.ServerType, item.ClientType);
var clientEntityInfo = _manager.CreateEntityInfo(clientEntity, serverEntityInfo.EntityState);
clientEntityInfo.UnmappedValuesMap = serverEntityInfo.UnmappedValuesMap;
clientEntityInfo.OriginalValuesMap = serverEntityInfo.OriginalValuesMap;
clientEntityInfo.AutoGeneratedKey = serverEntityInfo.AutoGeneratedKey;
clientEntityInfo.ForceUpdate = serverEntityInfo.ForceUpdate;
clientGroup.Add(clientEntityInfo);
}
// Update the key mappings. Used when new items are created.
var serverName = item.ServerType.FullName;
var clientName = item.ClientType.FullName;
keyMappings.ForEach(keyMapping =>
{
if (keyMapping.EntityTypeName == serverName)
keyMapping.EntityTypeName = clientName;
});
}
}
}
This happens anytime there is a delete. It could be by itself or it could come along with other changes. Either way, I always get that error.
I am using the EF as a designer for my metadata. Maybe something isn't right there? Still, not sure why that would only affect deletes.
The WebActivator
package has been deprecated, and projects are encouraged to use the newer WebActivatorEx
package, because it is strongly named. https://nuget.org/packages/WebActivatorEx/
I use vs2017 to create a jumpstart web application project, but when i try to install the Breeze.Server.AspNetCore.NetFramework from nuget, I get the follow errors:
Restoring packages for D:\work\Projects\atom-jumpstart-net\Jumpstart.Web\Jumpstart.Web.csproj...
Package Breeze.Server.AspNetCore.NetFramework 0.1.3 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Breeze.Server.AspNetCore.NetFramework 0.1.3 supports: net (.NETFramework,Version=v0.0)
Package Breeze.Server.Core 0.1.3 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Breeze.Server.Core 0.1.3 supports: net (.NETFramework,Version=v0.0)
Package Breeze.Server.Persistence 0.1.3 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Breeze.Server.Persistence 0.1.3 supports: net (.NETFramework,Version=v0.0)
One or more packages are incompatible with .NETCoreApp,Version=v1.0.
Package restore failed. Rolling back package changes for 'Jumpstart.Web'.
I have been experiencing slow performance randomly. A slow request is happening perhaps once out of 100 requests. The requests before that, and after that are just fine. It's also not the first request so it can't be initialization of entity framework. The request and the response do not change.
In this screenshot I used the Postman chrome plugin to reproduce this. I see the same thing when I call the API from my website.I am using the .net client of Breeze with EF6.1.3 and Web API 2. Any idea how I can troubleshoot this?
Is the project dead?
Are there any plans to support the new asp.net core?
It would be nice to disable the expand option for purposes of security. As it is, we cannot directly expose the db context, instead we must use toList which impacts performance.
This may not be for you but to do with EF but I wonder if you have experienced it.
If I apply an EnableQuery attribute to an endpoint (eq to specify max take count &c although this one is empty..)
[EnableQuery()]
[HttpGet]
public IQueryable<HistoryDataLogNodeValue> DataLogNodeValues() { return _context.Context.DataLogNodeValues; }
then paging stops working
here is the sql generated when the enablequery attribute is present
exec sp_executesql N'SELECT TOP (@p__linq__5)
[Project2].[row_number] AS [row_number],
[Project2].[Id] AS [Id],
[Project2].[Value] AS [Value],
[Project2].[UnitNodeId] AS [UnitNodeId],
[Project2].[RuntimeId] AS [RuntimeId],
[Project2].[IsCurrent] AS [IsCurrent],
[Project2].[MyCommandId] AS [MyCommandId],
[Project2].[Timestamp] AS [Timestamp],
[Project2].[CreatedOn] AS [CreatedOn],
[Project2].[ModifiedOn] AS [ModifiedOn],
[Project2].[UserIdCreated] AS [UserIdCreated]
FROM ( SELECT [Project2].[Id] AS [Id], [Project2].[Value] AS [Value], [Project2].[UnitNodeId] AS [UnitNodeId], [Project2].[RuntimeId] AS [RuntimeId], [Project2].[IsCurrent] AS [IsCurrent], [Project2].[MyCommandId] AS [MyCommandId], [Project2].[Timestamp] AS [Timestamp], [Project2].[CreatedOn] AS [CreatedOn], [Project2].[ModifiedOn] AS [ModifiedOn], [Project2].[UserIdCreated] AS [UserIdCreated], row_number() OVER (ORDER BY [Project2].[Value] DESC) AS [row_number]
FROM ( SELECT
[Limit1].[Id] AS [Id],
[Limit1].[Value] AS [Value],
[Limit1].[UnitNodeId] AS [UnitNodeId],
[Limit1].[RuntimeId] AS [RuntimeId],
[Limit1].[IsCurrent] AS [IsCurrent],
[Limit1].[MyCommandId] AS [MyCommandId],
[Limit1].[Timestamp] AS [Timestamp],
[Limit1].[CreatedOn] AS [CreatedOn],
[Limit1].[ModifiedOn] AS [ModifiedOn],
[Limit1].[UserIdCreated] AS [UserIdCreated]
FROM ( SELECT TOP (@p__linq__2) [Project1].[Id] AS [Id], [Project1].[Value] AS [Value], [Project1].[UnitNodeId] AS [UnitNodeId], [Project1].[RuntimeId] AS [RuntimeId], [Project1].[IsCurrent] AS [IsCurrent], [Project1].[MyCommandId] AS [MyCommandId], [Project1].[Timestamp] AS [Timestamp], [Project1].[CreatedOn] AS [CreatedOn], [Project1].[ModifiedOn] AS [ModifiedOn], [Project1].[UserIdCreated] AS [UserIdCreated]
FROM ( SELECT [Project1].[Id] AS [Id], [Project1].[Value] AS [Value], [Project1].[UnitNodeId] AS [UnitNodeId], [Project1].[RuntimeId] AS [RuntimeId], [Project1].[IsCurrent] AS [IsCurrent], [Project1].[MyCommandId] AS [MyCommandId], [Project1].[Timestamp] AS [Timestamp], [Project1].[CreatedOn] AS [CreatedOn], [Project1].[ModifiedOn] AS [ModifiedOn], [Project1].[UserIdCreated] AS [UserIdCreated], row_number() OVER (ORDER BY [Project1].[Value] DESC, [Project1].[Id] ASC) AS [row_number]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Value] AS [Value],
[Extent1].[UnitNodeId] AS [UnitNodeId],
[Extent1].[RuntimeId] AS [RuntimeId],
[Extent1].[IsCurrent] AS [IsCurrent],
[Extent1].[MyCommandId] AS [MyCommandId],
[Extent1].[Timestamp] AS [Timestamp],
[Extent1].[CreatedOn] AS [CreatedOn],
[Extent1].[ModifiedOn] AS [ModifiedOn],
[Extent1].[UserIdCreated] AS [UserIdCreated]
FROM [dbo].[HistoryDataLogNodeValues] AS [Extent1]
WHERE [Extent1].[UnitNodeId] = @p__linq__0
) AS [Project1]
) AS [Project1]
WHERE [Project1].[row_number] > @p__linq__1
ORDER BY [Project1].[Value] DESC, [Project1].[Id] ASC
) AS [Limit1]
WHERE [Limit1].[UnitNodeId] = @p__linq__3
) AS [Project2]
) AS [Project2]
WHERE [Project2].[row_number] > @p__linq__4
ORDER BY [Project2].[Value] DESC',N'@p__linq__0 int,@p__linq__1 int,@p__linq__2 int,@p__linq__3 int,@p__linq__4 int,@p__linq__5 int',@p__linq__0=1,@p__linq__1=10,@p__linq__2=10,@p__linq__3=1,@p__linq__4=10,@p__linq__5=10
go
and here when it is absent
exec sp_executesql N'SELECT TOP (@p__linq__2)
[Project1].[Id] AS [Id],
[Project1].[Value] AS [Value],
[Project1].[UnitNodeId] AS [UnitNodeId],
[Project1].[RuntimeId] AS [RuntimeId],
[Project1].[IsCurrent] AS [IsCurrent],
[Project1].[MyCommandId] AS [MyCommandId],
[Project1].[Timestamp] AS [Timestamp],
[Project1].[CreatedOn] AS [CreatedOn],
[Project1].[ModifiedOn] AS [ModifiedOn],
[Project1].[UserIdCreated] AS [UserIdCreated]
FROM ( SELECT [Project1].[Id] AS [Id], [Project1].[Value] AS [Value], [Project1].[UnitNodeId] AS [UnitNodeId], [Project1].[RuntimeId] AS [RuntimeId], [Project1].[IsCurrent] AS [IsCurrent], [Project1].[MyCommandId] AS [MyCommandId], [Project1].[Timestamp] AS [Timestamp], [Project1].[CreatedOn] AS [CreatedOn], [Project1].[ModifiedOn] AS [ModifiedOn], [Project1].[UserIdCreated] AS [UserIdCreated], row_number() OVER (ORDER BY [Project1].[Value] DESC) AS [row_number]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Value] AS [Value],
[Extent1].[UnitNodeId] AS [UnitNodeId],
[Extent1].[RuntimeId] AS [RuntimeId],
[Extent1].[IsCurrent] AS [IsCurrent],
[Extent1].[MyCommandId] AS [MyCommandId],
[Extent1].[Timestamp] AS [Timestamp],
[Extent1].[CreatedOn] AS [CreatedOn],
[Extent1].[ModifiedOn] AS [ModifiedOn],
[Extent1].[UserIdCreated] AS [UserIdCreated]
FROM [dbo].[HistoryDataLogNodeValues] AS [Extent1]
WHERE [Extent1].[UnitNodeId] = @p__linq__0
) AS [Project1]
) AS [Project1]
WHERE [Project1].[row_number] > @p__linq__1
ORDER BY [Project1].[Value] DESC',N'@p__linq__0 int,@p__linq__1 int,@p__linq__2 int',@p__linq__0=1,@p__linq__1=10,@p__linq__2=10
go
I am using EF6.1.1 and Microsoft.AspNet.WebApi.OData v 5.2.0
I am attempting to use Automapper to use DTOs in the Aspnet Core version of Breeze. The difficulty I'm am facing right now is that I can't use expand. If I do, it won't generate a good query and I get an error.
The aspnet classic (?) approach using ODataQueryOptions doesn't seem to be an option now because of the decoupling from OData.
Is there a way to get this information so I can pass it along to automapper, or is this more of a feature request?
Hello,
I am not sure if this issue relates to Breeze Context Provider or EF SqlProvider but here it goes.
We have an ASP.NET Web API with EF 6.1.3 model and today I noticed an interesting issue where if we request from the API method to sort by, expand and take/skip 20 rows and expand on multiple tables/entities, this translates to the following SQL query: JOIN on all rows in the primary table/entity against all expands, then sort then skip. Shouldn't it expand after filtering, skipping and sorting?
ISet<> do not implement ICollection. Thats the reason why expand() does not work on generic ISet<> navigation properties.
https://github.com/Breeze/breeze.server.net/blob/master/Breeze.ContextProvider.NH/NHExpander.cs#L64
edit: removed IList<> because it works
I'm trying to use Breeze with ASP.NET Core and Full Entity Framework
My issue is when I call this api:
http://localhost:50969/breeze/Students?$orderby=Id&$top=3&$inlinecount=allpages
this message return to me:
"This EntityQuery ctor requires a valid json string. The following is not json: $orderby=Id"
{ $id: "2", $type: "Breeze.AspNetCore.ErrorDto, Breeze.AspNetCore.NetFramework", Code: 0, Message: "This EntityQuery ctor requires a valid json string. The following is not json: $orderby=Id", StackTrace: " at Breeze.Core.EntityQuery..ctor(String json) at Breeze.AspNetCore.BreezeQueryFilterAttribute.OnActionExecuted(ActionExecutedContext context) at Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute.<OnActionExecutionAsync>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextExceptionFilterAsync>d__24.MoveNext()", EntityErrors: null }
but when I call the same api without parameters its works fine and returns json like this:
[ { $id: "3", $type: "funny2.Data.Models.Student, funny2.Data", ID: 1, LastName: "Ali", FirstMidName: "Sami", EnrollmentDate: "2017-06-23T23:28:52.873", Enrollments: null } ]
Is there any sample working fine on ASP.NET Core
The C# Breeze source has many wonderful XML comments adorning its types, methods, etc. The C# compiler happily creates a XML file (a la Breeze.ContextProvider.xml
, assuming generation is enabled and using the defaults), which causes the documentation to show up directly in Visual Studio IntelliSense and metadata.
Alas, the NuGet packages don't include the .xml files. Including them would be a fine productivity boost for little effort.
When I attempt to generate metadata I get the below error. I am using EF Core with identity
System.NullReferenceException: Object reference not set to an instance of an object.
at Breeze.Persistence.EFCore.MetadataBuilder.BuildAssocName(INavigation prop) in C:\git\Breeze\breeze.server.net\AspNetCore\Breeze.Persistence.EFCore\MetadataBuilder.cs:line 138
at Breeze.Persistence.EFCore.MetadataBuilder.CreateNavProperty(INavigation p) in C:\git\Breeze\breeze.server.net\AspNetCore\Breeze.Persistence.EFCore\MetadataBuilder.cs:line 128
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToList()
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Breeze.Persistence.EFCore.MetadataBuilder.CreateMetaType(IEntityType et, Dictionary`2 dbSetMap) in C:\git\Breeze\breeze.server.net\AspNetCore\Breeze.Persistence.EFCore\MetadataBuilder.cs:line 89
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToList()
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Breeze.Persistence.EFCore.MetadataBuilder.GetMetadataFromContext(DbContext dbContext) in C:\git\Breeze\breeze.server.net\AspNetCore\Breeze.Persistence.EFCore\MetadataBuilder.cs:line 21
at Breeze.Persistence.EFCore.EFPersistenceManager`1.BuildJsonMetadata() in C:\git\Breeze\breeze.server.net\AspNetCore\Breeze.Persistence.EFCore\EFPersistenceManager.cs:line 109
at Breeze.Persistence.PersistenceManager.Metadata() in C:\git\Breeze\breeze.server.net\AspNetCore\Breeze.Persistence\PersistenceManager.cs:line 34
at MITSBusinessLib.Repositories.EventOrganizerRepo.MetaData() in C:\Users\Jason\Documents\MITSWebApp\MITSBusinessLib\Repositories\EventOrganizerRepo.cs:line 28
at MITSWebServices.Controllers.EventOrganizerController.Metadata() in C:\Users\Jason\Documents\MITSWebApp\MITSWebServices\Controllers\EventOrganizerController.cs:line 29
at lambda_method(Closure , Object , Object[] )
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
This is my Context
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using MITSDataLib.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace MITSDataLib.Contexts
{
public class MITSContext : IdentityDbContext<User>
{
public MITSContext(DbContextOptions<MITSContext> options): base(options)
{
//Do I need these with EF CORE?
//Configuration.ProxyCreationEnabled = false;
//Configuration.LazyLoadingEnabled = false;
}
public DbSet<WildApricotEvent> WaEvents { get; set; }
public DbSet<WildApricotRegistrationType> WaRegistrationTypes { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<Speaker> Speakers { get; set; }
public DbSet<Section> Sections { get; set; }
public DbSet<Event> Events { get; set; }
public DbSet<Day> Days { get; set; }
public DbSet<Person> People { get; set; }
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.