ASP.NET Web API 2 - 从POST方法解析JSON以动态查询数据库(ASP.NET Web API 2 - Parsing JSON from a POST method to query database dynamically)
我想公开我的数据库,以便可以将POST发送到我的控制器,然后用于构建查询。 我正在使用实体框架来构建我的数据上下文。 这里的想法是客户端会在POST主体中传递JSON。 从那里查询将使用JSON中指定的属性和值进行构建。 这里的踢球者是我不想硬编码值。 我希望以这种动态方式构建查询,以便对数据上下文所做的任何更改都将直接反映在代码中。
例如,我想:
[ { "NAME":"Random Name" }, { "NAME":"Random Name 2", "STATUS":"ACTIVE" } ]
要翻译成以下内容:
var query = FROM d in DataContext WHERE (x.NAME == "Random NAME 1") OR (X.NAME == "Random Name 2" AND X.STATUS == "ACTIVE")
请记住,可以选择超过60种可能的属性,并且数据模型可能会发生变化。
这是我的想法是将JSON解析为对象数组,循环遍历每个对象,然后遍历该对象的非空属性以动态构建查询。
这是我的代码与实际变量。
调节器
public class AgreementsController : ApiController { private AgreementRepository agreementRepository; public AgreementsController() { this.agreementRepository = new AgreementRepository(); } public AGREEMENT[] Post([FromBody]AGREEMENT[] Agreements) { return agreementRepository.PostAgreements(Agreements); } }
服务
public class AgreementRepository { private DataBaseEntities db = new DataBaseEntities(); public AGREEMENT[] PostAgreements(AGREEMENT[] Agreements) { List<AGREEMENT> a = new List<AGREEMENT>(); foreach (AGREEMENT agreement in Agreements) { /////Loop Through Possible Attributes and then /////Build queries based off of non null values. ////Append to List and return Agreement[] to controller } var agmts = a.ToArray<AGREEMENT>(); return agmts; } }
I would like to expose my database such that a POST can be made to my controller that would then be used to build a query. I am using entity framework to build my Data Contexts. The idea here is that the client would pass JSON in the POST body. From there queries will be build using the attributes and values specified in the JSON. The kicker here is that I do not want to hard code values. I would like this to build queries in such a dynamic way that any changes made to the data context will directly be reflected in the code.
For example I would like:
[ { "NAME":"Random Name" }, { "NAME":"Random Name 2", "STATUS":"ACTIVE" } ]
To translate to something like:
var query = FROM d in DataContext WHERE (x.NAME == "Random NAME 1") OR (X.NAME == "Random Name 2" AND X.STATUS == "ACTIVE")
Keeping in mind that there are over 60 possible attributes that could be chosen and the data model may change.
This my thinking is to parse the JSON into an object array, Loop through each object, and then loop through non null attributes of that object to dynamically build a query.
Here is my code with actual variables.
Controller
public class AgreementsController : ApiController { private AgreementRepository agreementRepository; public AgreementsController() { this.agreementRepository = new AgreementRepository(); } public AGREEMENT[] Post([FromBody]AGREEMENT[] Agreements) { return agreementRepository.PostAgreements(Agreements); } }
Service
public class AgreementRepository { private DataBaseEntities db = new DataBaseEntities(); public AGREEMENT[] PostAgreements(AGREEMENT[] Agreements) { List<AGREEMENT> a = new List<AGREEMENT>(); foreach (AGREEMENT agreement in Agreements) { /////Loop Through Possible Attributes and then /////Build queries based off of non null values. ////Append to List and return Agreement[] to controller } var agmts = a.ToArray<AGREEMENT>(); return agmts; } }
原文:https://stackoverflow.com/questions/48451164
最满意答案
您应该能够在转换中使用补间功能完成此操作。 补间函数将在转换的每个滴答上触发,并且是每个滴答调用函数的一种方法。
补间方法需要一个属性名称(因为它旨在为属性提供自定义插值),但这可以是虚拟属性,也可以是未更改的属性(如下面的示例所示)。 有关方法的文档在这里 。
在我的示例中,我使用补间函数在屏幕上移动时拉出圆圈的x属性(井,cx属性):
.tween("attr.fill", function() { var node = this; return function(t) { console.log(node.getAttribute("cx")); } })
以下是工作中的一小段内容:
var svg = d3.select("body").append("svg") .attr("width",400) .attr("height",400); var circle = svg.append("circle") .attr("cx",20) .attr("cy",20) .attr("r",10); circle.transition() .attr("cx",380) .attr("cy",20) .tween("attr.fill", function() { var node = this; return function(t) { console.log(node.getAttribute("cx")); } }) .duration(1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
You should be able to accomplish this using a tween function in your transition. A tween function will trigger on every tick of the transition and is one way to call a function every tick.
The tween method needs an attribute name (as it is intended to provide custom interpolation for an attribute), but this can be a dummy attribute, or one that isn't changed (as in my example below). Documentation on the method is here.
In my example I pull the x property (well, cx property) of a circle as it moves across the screen, using a tween function:
.tween("attr.fill", function() { var node = this; return function(t) { console.log(node.getAttribute("cx")); } })
Here is a snippet of it at work:
var svg = d3.select("body").append("svg") .attr("width",400) .attr("height",400); var circle = svg.append("circle") .attr("cx",20) .attr("cy",20) .attr("r",10); circle.transition() .attr("cx",380) .attr("cy",20) .tween("attr.fill", function() { var node = this; return function(t) { console.log(node.getAttribute("cx")); } }) .duration(1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
相关问答
更多-
您应该能够在转换中使用补间功能完成此操作。 补间函数将在转换的每个滴答上触发,并且是每个滴答调用函数的一种方法。 补间方法需要一个属性名称(因为它旨在为属性提供自定义插值),但这可以是虚拟属性,也可以是未更改的属性(如下面的示例所示)。 有关方法的文档在这里 。 在我的示例中,我使用补间函数在屏幕上移动时拉出圆圈的x属性(井,cx属性): .tween("attr.fill", function() { var node = this; return function(t) ...
-
如何使用d3.js更新轴(How to update axis using d3.js)[2023-07-17]
看起来您更新轴时使用错误的选择器: svg.selectAll("g .y.axis") .call(yAxis); svg.selectAll("g .x.axis") .call(xAxis); 也许应该看: svg.selectAll("g.y.axis") .call(yAxis); svg.selectAll("g.x.axis") .call(xAxis); It looks like you are ... -
尝试创建一个新的Date对象,然后将x轴的刻度传递给格式化程序: .tickFormat(function(d) { return d3.time.format('%b %d')(new Date(d)); }) 请参阅d3.time.format的文档,了解如何自定义格式化字符串。 Try creating a new Date object before the tick for the x-axis gets passed to the formatter: .tickFormat(function ...
-
这是一个保证金问题。 你的有效身高是height - margin.top - margin.bottom 。 我已相应修复了这个例子(可读性提高了)。 要按顺序使用数月,您必须使用,是的,几个月来初始化比例。 然后使用比例将序数值映射到x标度值,例如x0Scale(d.Month) 。 function createGroupchart() { var width = 500; var height = 180; var margin = { 'top' : 5, ...
-
这是一个工作的jsfiddle: https ://jsfiddle.net/kmandov/d61gtadm/3/ 这就是你如何达到预期的效果: 问题a。)每天的垂直刻度: 首先,创建一个新的主轴并将tickSize设置为-height ,这样刻度就会一直在你的图表中: var majorAxis = d3.svg.axis() .scale(x_scale) .orient('bottom') .ticks(d3.time.day, 1) .tickSize(-height) ...
-
使用d3轴的刻度方法。 由于x轴的刻度格式是时间,因此您可以指定计数和刻度格式。 var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(d3.time.day, 2); var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5); 您可以从此处参考d3 svg轴以及此处的时间格式 Use ticks method of d3 axis. Since tick format of x a ...
-
在d3js中,是否可以在x轴上转换固定范围的值?(In d3js, is it possible to transition a fixed range of values on x-axis?)[2023-02-02]
您的tick函数将域设置为: [1,15] then [2,15] then [3,15] etc... 这是更接近结束的缩放。 你想要的是滚动效果(比如N为5个刻度): [1,5] then [2,6] then [3,7] etc... 所以: function tick() { var curD = x.domain(); // get current domain if (curD[1] >= 15){ // at 15 reset to 1,5 curD[0] = 0; ... -
当您设置单击处理程序时,如下所示: .on("click", (d) => click(d)) 胖箭符号保留了this的上下文,所以它指的是你的类的实例。 但是你的处理程序: function click(d) { d3.select(this).select("circle").transition() .duration(750) .attr("r", 16); } 期待this是被点击的g 。 所以,设置你的处理程序,如: .on("click", clic ...
-
尝试改变: var lineGridLines = d3.svg.line() .interpolate('step-after') .x(function(d) { return xScaleGridLines(d.x); }) .y(function(d) { return yScaleGridLines(d.y); }); 至 : var lineGridLines = d3.svg.line() .interpolate('step-after') ...
-
在d3.js中设置X轴标签(Setting X-axis label in d3.js)[2022-02-20]
你必须使用SVG文本标签。 假设您以这种方式创建X轴: var xAxis = svg.append("g") .attr({ "class": "x axis", transform: "translate(0," + h + ")" }) .call(xAxis); 您选择文本,然后应用转换: xAxis.selectAll ...