devexpress / devextreme.aspnet.data Goto Github PK
View Code? Open in Web Editor NEWDevExtreme data layer extension for ASP.NET
License: MIT License
DevExtreme data layer extension for ASP.NET
License: MIT License
See the Filter row does not filter properly for nullable date field ticket for details.
T458279.zip
pivotStore = DevExpress.data.AspNet.createStore({ "loadUrl": "/Detail/Get", });
Now the DevExtreme.AspNet.Data library has several incompatibility issues with the ASP.NET Core 1.0.0 release version.
For instance, the Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.Success method signature was changed in
this commit and the DevExtreme.AspNet.Data.DataSourceLoadOptionsBinder.BindModelAsync method raises the System.MissingMethodException error.
Steps:
in Sample site, enable remote grouping and group by ShipRegion
"Custom Model Binder" and "Controller Example" don't provide examples for MVC 5 controllers.
Test Name: FilterExpressionCompilerTypeConversionTests.IntegralFromFloatString
It is necessary to add info about:
DataSourceLoadOptionsBinder
implementation.DataSourceLoadOptions
in a controller.DevExpress.data.AspNet.createStore
See the DataGrid MVC Wrapper - Summary for TimeSpan values is not calculated ticket for details.
T458296.zip
Currently the DataSourceLoader does not support the $select functionality. At the minimum, can you please make the following class public so that I can replicate that functionality on my side by using this class?
DevExtreme.AspNet.Data.DataSourceLoadResult
You can see how I'm using that here: https://www.devexpress.com/Support/Center/Question/Details/T430399
To reproduce the issue input any text to the find panel.
timeSpanIssue.zip
DevExtreme.AspNet.Data of version 1.3.0-rc3 returns the response in a format like {data: [{id: 1, name: "Two"}]} when the byKey method is used. Wrapping the data array into the "data" field leads to nothing being resolved. This breaks DevExtreme lookup editors. See the screencast that illustrates this and the sample project is attached.
WebApplication1.zip
All working fine with 1.2.5, however when upgrading to 1.2.6 count queries fail.
In DataSourceLoader:100
return (int)source.Provider.Execute(builder.BuildCountExpr(source.Expression));
throws something along the lines: cannot convert IEnumerable<int> to IEnumerable<object>
Hallo,
The dxDataGrid has an option: sortByGroupSummaryInfo. This allows sorting on grouped columns.
Not sure what else to type... if you need more info let me know.
Regards,
Erik
Please make DataSourceLoadResult
a public class so everyone can use it.
In our case it's required to access the result data in order to calculate some properties on the returned objects.
Broken here
@RomanTsukanov
Now that we have https://www.npmjs.com/package/devextreme-aspnet-data would you please update README accordingly?
When request is aborted before respnse is received.
This feature was requested in the DevExpress support center several times
Hallo,
When I get large values (type of double) back from our database, I'm getting the following error:
System.OverflowException: Value was either too large or too small for a Decimal.
at System.Decimal..ctor(Double value)
at System.Double.System.IConvertible.ToDecimal(IFormatProvider provider)
at DevExtreme.AspNet.Data.Aggregation.SumAggregator`1.Step(T container, String selector)
at DevExtreme.AspNet.Data.Aggregation.AggregateCalculator`1.Step(Object obj, Aggregator`1[] aggregators, String[] selectors)
at DevExtreme.AspNet.Data.Aggregation.AggregateCalculator`1.ProcessItem(Object item)
at DevExtreme.AspNet.Data.Aggregation.AggregateCalculator`1.Run()
at DevExtreme.AspNet.Data.DataSourceLoader.Load[T](IQueryable`1 source, DataSourceLoadOptionsBase options)
Regards,
Erik
I've following class setting:
public class Result
{
public int Value { get; set; }
public string Name { get; set; }
}
public class ResultExtended : Result
{
public int CustomerId { get; set; }
}
When I use following call using the filter option
var query = _provider.Get<Address>()
.Where(a => a.ID > 10)
.Select(a => new ResultExtended { CustomerId = a.County, Name = a.City });
var options = new TestLoadOptions
{
Skip = 0,
Take = 10,
Filter = new List<object> { "Name", "contains", "test" }
};
var result = DataSourceLoader.Load(query, options);
The resulting query looks like
from Address a in Query(CHG.Demo.Objects.Address) where ([a].ID > 10) where new ResultExtended() {CustomerId = [a].County, Name = [a].City}.Name.ToLower().Contains("test") select new ResultExtended() {CustomerId = [a].County, Name = [a].City} => Take(10)
But when I express the same query "directly"
var query = _provider.Get<Address>()
.Where(a => a.ID > 10)
.Select(dto => new ResultExtended { CustomerId = dto.County, Name = dto.City })
.Where(obj => obj.Name.ToLower().Contains("test"))
.Take(10);
var result = query.ToList();
the resulting query is correct
from Address a in Query(CHG.Demo.Objects.Address) where ([a].ID > 10) where [a].City.ToLower().Contains("test") select new ResultExtended() {CustomerId = [a].County, Name = [a].City} => Take(10)
I guess the expression builder if the DataSourceLoader
creates a wrong expression when applying the filter.
Update:
By comparing the two expression trees I found out that the MemberExpression obj.Name
are different. The MemberInfo of the first query says that the ReflectedType
is ResultExtended
, the value for the second query is Result
.
So when I call it
var result = DataSourceLoader.Load<Result>(query, options);
the error is gone.
I've set up a grid with total summaries of count and a sum.
Everytime I change the page, the summaries and total count are re-queried. No filter, sorting or grouping has been changed, just the page (Skip/take parameter).
I would love to see that the summaries and totalcount are only fetched on the first page request and after the filter, sorting or grouping have been changed. Any time else the summaries stays the same and should't be fetched on every pagination operation.
I'd like to be able to register my own calculators with your framework. You can see how I'm doing it below. It would be nice if this was incorporated into your library - you can make the changes or allow me to commit.
In DevExtreme.AspNet.Data.Aggregation.AggregateCalculator:
private static Dictionary<String, Type> customCalculators = new Dictionary<string, Type>();
public static void registerCustomCalc(String name, Type type)
{
customCalculators[name] = type;
}
Aggregator<T> CreateAggregator(string summaryType)
{
/* existing calculators */
Type type;
if (customCalculators.TryGetValue(summaryType, out type))
return Activator.CreateInstance(type, _accessor) as Aggregator<T>;
throw new NotSupportedException();
}
Usage in my service:
DevExtreme.AspNet.Data.Aggregation.AggregateCalculator<PositionModel>.registerCustomCalc("countLS", typeof(CountLSAggregator<PositionModel>));
Then in dxDataGrid:
totalItems: [
{
column: "Quantity",
summaryType: "countLS",
alignByColumn: true
},
. . .
Why?
Drawbacks
DataSourceLoadOptions
and DataSourceLoadOptionsBinder
must be defined externally (like here).Work started in https://github.com/AlekseyMartynov/DevExtreme.AspNet.Data/tree/no-mvc
@IlyaKhD when you have a minute, please review and share your thoughts
To prevent querying for excessive amounts of data with large or missing take
parameter.
Hi!
I am tring to use dx.aspnet.data.js from typescript (Angular 2).
As far as I understand it is needed to create interface definition file - dx.aspnet.data.d.ts
Maybe somebody did it? Or there is some example of using devextreme's aspnet data store from Angular 2?
Once the grid is sorted by a column that has duplicated values, paging works wrong
T454358(new).zip
For example, if the load endpoint returns a JSON string, then the following error occurs:
dx.aspnet.data.js:225 Uncaught TypeError: Cannot use 'in' operator to search for 'totalCount' in abc
at createLoadExtra (dx.aspnet.data.js:225)
at dx.aspnet.data.js:148
at Object.<anonymous> (dx.aspnet.data.js:59)
...
Reason:
node_modules/devextreme/bundles/dx.all.d.ts(2206,22): error TS2430: Interface 'dxLoadPanelOptions' incorrectly extends interface 'dxOverlayOptions'.
Types of property 'animation' are incompatible.
Type 'AnimationOptions' has no properties in common with type '{ show?: AnimationOptions; hide?: AnimationOptions; }'.
Originally reported in https://www.devexpress.com/Support/Center/Question/Details/T483154
For instance, fitlering by 1/1/2016 produces the following query:
filter=[["OrderDate",">=","2015-12-31T21:00:00.000Z"],"and",["OrderDate","<","2016-01-01T21:00:00.000Z"]]
Starting with version 1.2.2, the Load
method throws the following exception:
Value cannot be null.
Parameter name: constructor
The following query:
var q = _nwind.Orders
.OrderBy(o => o.Freight)
.GroupBy(o => new { o.Freight })
.Select(g => new { g.Key });
is translated into
SELECT
[Distinct1].[C1] AS [C1],
[Distinct1].[Freight] AS [Freight]
FROM ( SELECT DISTINCT
[Extent1].[Freight] AS [Freight],
1 AS [C1]
FROM [dbo].[Orders] AS [Extent1]
) AS [Distinct1]
ordering is lost.
Possible solution: order groups by keys.
[Fact]
public void Test1() {
DataSourceLoader.Load(
new[] {
new KeyValuePair<int, int>(1, 2)
},
new SampleLoadOptions {
Filter = new object[] { "Key", 0 }
}
);
}
throws: System.ArgumentNullException: 'Value cannot be null.'
It can be reproduced with the Widget Gallery for ASP.NET MVC Wrappers using the following code:
Scheduler.cshtml:
@(Html.DevExtreme().Scheduler()
.DataSource(d => d.WebApi()
.Controller("SchedulerData")
.LoadAction("Appointments")
.Key("OrderID")
)
.Editing(e => e.AllowAdding(true).AllowDeleting(false))
...
)
SchedulerDataController.cs:
public class SchedulerDataController : ApiController {
...
[HttpPut]
public HttpResponseMessage Put(FormDataCollection form) {
var key = Convert.ToInt32(form.Get("key"));
var values = JsonConvert.DeserializeObject<JObject>(form.Get("values"));
var order = _nwind.Orders.Find(key);
order.OrderDate = (DateTime)values["OrderDate"];
order.ShippedDate = (DateTime)values["ShippedDate"];
order.ShipVia = (int)values["ShipVia"];
Validate(order);
if(!ModelState.IsValid)
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState.GetFullErrorMessage());
_nwind.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK);
}
}
If the LoadOptions have a single TotalSummary with a "count" aggregate, the DataSourceLoader will execute first a "SELECT Count(*).." statement to get the overall amount of items (required for pagination I guess) and then executes a statement WITHOUT a top/skip because it want's to calculate the summary in memory.
For this case (which very often exists) it could be much better if the summary is not calculated in memory and the already retrieved count value will be used.
The DataSourceLoader.Load
method returns an empty result with enum typed fields.
Debugging a user's sample project in the T412494 ticket, I reproduced this issue with the simple code below:
using System;
using System.Collections.Generic;
using DevExtreme.AspNet.Data;
using Newtonsoft.Json;
namespace EnumField {
class Program {
public enum OrderType { One, Two }
class Order {
public Enum OrderType { get; set; }
}
public partial class DataSourceLoadOptions : DataSourceLoadOptionsBase { }
static void Main(string[] args) {
var orders = new List<Order>() {
new Order { OrderType = OrderType.One },
new Order { OrderType = OrderType.Two }
};
var loadOptions = new DataSourceLoadOptions() {
Filter = new List<object>(new object[] { "OrderType", "=", 1 })
};
var result = DataSourceLoader.Load(orders, loadOptions);
Console.WriteLine(JsonConvert.SerializeObject(result));
}
}
}
I've an error in my setup. The filter criteria does not fit to the queried entity.
Unfortunately the error ("'LeaseState' is not a member of type 'MyEntity'") won't bubble up to the developer. Instead the query will be created with an .Where(false)
expression.
In some scenarios no one would even notice there's an error because the grid just shows no data.
Either let the exception (FilterExpressionCompiler.CompileCore) bubble up to the caller or provide any mechanism where the developer can check if any error occurred.
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.