Subsonic Syntax Question (with GroupBy) - syntax

Is there a way to do this :
SubSonic.Where filter = new SubSonic.Where();
filter.ColumnName = Region.Columns.Region;
filter.Comparison = SubSonic.Comparison.IsNot;
filter.ParameterValue = null;
SubSonic.Aggregate orderBy = new SubSonic.Aggregate(Region.Columns.RegionName, SubSonic.AggregateFunction.GroupBy);
RegionCollection regions = new RegionCollection().Where(filter).GroupBy(groupBy).Load();
The "GroupBy" part in the last line doesn't compile... (I'm using SubSonic 2.1)

Just in case there isn't a reason you need the old Where construct:
SubSonic.Aggregate groupBy = new SubSonic.Aggregate(Region.Columns.RegionName, SubSonic.AggregateFunction.GroupBy);
RegionCollection regions = new SubSonic.Select(groupBy).From(Region.Schema).Where(Region.RegionColumn).IsNotNull().ExecuteAsCollection<RegionCollection>();

With Collections you can use OrderByAsc and OrderByDesc but they both only allow passing a string as a parameter. And the SubSonic.AggregateFunction.GroupByprobably isn't what you want.
Try this instead:
var result = new RegionCollection().OrderByAsc(Region.Columns.RegionName).Load();

Related

Problem in adding multi filter to odata service

I have the following code. I am trying to read 3 different values for PO from input fields then displaying the result in list. Program is working fine for single input but for multiple inputs i am facing issues.
var oV1 = this.getView().byId("oInput").getValue();
var oV2 = this.getView().byId("oInput1").getValue();
var oV3 = this.getView().byId("oInput2").getValue();
var oFilter = [new sap.ui.model.Filter("Ebeln", sap.ui.model.FilterOperator.Contains, oV1)];
var oFilter1 = [new sap.ui.model.Filter("Ebeln", sap.ui.model.FilterOperator.Contains, oV2)];
var oFilter2 = [new sap.ui.model.Filter("Ebeln", sap.ui.model.FilterOperator.Contains, oV3)];
var orFilter =new Array(new sap.ui.model.Filter({filters:[oFilter, oFilter1, oFilter2],and:true}));
var oView1 = this.getView();
var oTable = oView1.byId("myTable");
var oBinding = oTable.getBinding("items");
if(oV1 === "")
{
oBinding.filter( [] );
oBinding.refresh(true);
}
else
{
oBinding.filter(orFilter);
At the above oBinding.filter I am receiving following error.
Filter in Aggregation of Multi filter has to be instance of sap.ui.model.Filter -
Unable to get property 'replace' of undefined or null reference
Please help.
You wrapped your filters in 1000 layers of Arrays which doesn't make sense.
Just create a single array which contains Filter objects:
// Filter, FilterOperator, and FilterType required from "sap/ui/model/*"
const aFilter = [
new Filter("Ebeln", FilterOperator.Contains, sV1),
new Filter("Ebeln", FilterOperator.Contains, sV2),
new Filter("Ebeln", FilterOperator.Contains, sV3),
];
oListBinding.filter(aFilter, FilterType.Application);
I know this isn't a code review but some suggestions:
No one uses new Array(). Just use [].
Also you used Hungarian notation but every one of your variable names begins with o. o means object. Some of your variables are not objects but strings (like oV1, better would be sV1) or arrays.
For the filters aggregation, sap.ui.model.Filter accepts a Filter[]. But because oFilter already is a Filter[], [oFilter, oFilter1, oFilter2] is a Filter[][], so that won't work.
To make it work, just remove the surrounding [] from the filter definitions, like so:
var oFilter = new Filter(...);.

What is the performance optimum (or even better coding practise) for writing this Linq query

I am new to linq so please excuse me if I am asking a very basic question:
paymentReceiptViewModel.EntityName = payment.CommitmentPayments.First().Commitment.Entity.GetEntityName();
paymentReceiptViewModel.HofItsId = payment.CommitmentPayments.First().Commitment.Entity.ResponsiblePerson.ItsId;
paymentReceiptViewModel.LocalId = payment.CommitmentPayments.First().Commitment.Entity.LocalEntityId;
paymentReceiptViewModel.EntityAddress = payment.CommitmentPayments.First().Commitment.Entity.Address.ToString();
This code is too repetitive and I am sure there is a better way of writing this.
Thanks in advance for looking this up.
Instead of executing query at each line, get commitment entity once:
var commitment = payment.CommitmentPayments.First().Commitment.Entity;
paymentReceiptViewModel.EntityName = commitment.GetEntityName();
paymentReceiptViewModel.HofItsId = commitment.ResponsiblePerson.ItsId;
paymentReceiptViewModel.LocalId = commitment.LocalEntityId;
paymentReceiptViewModel.EntityAddress = commitment.Address.ToString();
It depends a bit on what you are selecting to, you cannot select from one entity into another in Linq to Entities. If you are using LINQ to SQL and creating the paymentReceiptModel, you can do this.
var paymentReceiptModel = payment.CommitmentPayments.select(x=>new{
EntityName = x.Commitment.Entity.GetEntityName(),
HofItsId = x.Commitment.Entity.ResponsiblePerson.ItsId,
LocalId = x.Commitments.Entity.LocalEntityId,
EntityAddress = x.Commitment.Entity.Address
}).FirstOrDefault();
If you are using an already instantiated paymentReceiptModel and just need to assign properties then you are better looking to the solution by lazyberezovsky.
To get around the limitation in Linq to Entities, if that is what you are using, you could do this
var result = payment.CommitmentPayments.select(x=>x);
var paymentReceiptModel= result.select(x=>new
{
EntityName = x.Commitment.Entity.GetEntityName(),
HofItsId = x.Commitment.Entity.ResponsiblePerson.ItsId,
LocalId = x.Commitments.Entity.LocalEntityId,
EntityAddress = x.Commitment.Entity.Address
}).FirstOrDefault();
This essentially, makes the majority of your query Linq to Objects, only the first line is Linq to Entities

Multiple rows update without select

An old question for Linq 2 Entities. I'm just asking it again, in case someone has came up with the solution.
I want to perform query that does this:
UPDATE dbo.Products WHERE Category = 1 SET Category = 5
And I want to do it with Entity Framework 4.3.1.
This is just an example, I have a tons of records I just want 1 column to change value, nothing else. Loading to DbContext with Where(...).Select(...), changing all elements, and then saving with SaveChanges() does not work well for me.
Should I stick with ExecuteCommand and send direct query as it is written above (of course make it reusable) or is there another nice way to do it from Linq 2 Entities / Fluent.
Thanks!
What you are describing isnt actually possible with Entity Framework. You have a few options,
You can write it as a string and execute it via EF with .ExecuteSqlCommand (on the context)
You can use something like Entity Framework Extended (however from what ive seen this doesnt have great performance)
You can update an entity without first fetching it from db like below
using (var context = new DBContext())
{
context.YourEntitySet.Attach(yourExistingEntity);
// Update fields
context.SaveChanges();
}
If you have set-based operations, then SQL is better suited than EF.
So, yes - in this case you should stick with ExecuteCommand.
I don't know if this suits you but you can try creating a stored procedure that will perform the update and then add that procedure to your model as a function import. Then you can perform the update in a single database call:
using(var dc = new YourDataContext())
{
dc.UpdateProductsCategory(1, 5);
}
where UpdateProductsCategory would be the name of the imported stored procedure.
Yes, ExecuteCommand() is definitely the way to do it without fetching all the rows' data and letting ChangeTracker sort it out. Just to provide an example:
Will result in all rows being fetched and an update performed for each row changed:
using (YourDBContext yourDB = new YourDBContext()) {
yourDB.Products.Where(p => p.Category = 1).ToList().ForEach(p => p.Category = 5);
yourDB.SaveChanges();
}
Just a single update:
using (YourDBContext yourDB = new YourDBContext()) {
var sql = "UPDATE dbo.Products WHERE Category = #oldcategory SET Category = #newcategory";
var oldcp = new SqlParameter { ParameterName = "oldcategory", DbType = DbType.Int32, Value = 1 };
var newcp = new SqlParameter { ParameterName = "newcategory", DbType = DbType.Int32, Value = 5 };
yourDB.Database.ExecuteSqlCommand(sql, oldcp, newcp);
}

Read from CellSet using LINQ

AdomdCommand cmd = new AdomdCommand(commandText, conn);
CellSet cs = cmd.ExecuteCellSet();
var result = from a in cs
select new
{...};
Is it possible to use LINQ to read from CellSet? I have tried using DataTable instead of CellSet but it's much slower (Example: I took a query that using DataTable takes ~45 sec to execute, but using CellSet it takes ~5 sec).
The error I get when trying to use LINQ:
Could not find an implementation of the query pattern for source type
'Microsoft.AnalysisServices.AdomdClient.CellSet'. 'Select' not found.
UPDATE:
I have tried Enrico's suggestion and so far it doesn't return any errors. Next problem is how to read a value from a cell. Here's what I have tried so far:
var result = from cell in cs.Cells.Cast<Cell>()
select new searchResultsPolicy
{
PolicyNumber = ...
InsuredName = cell.Field<string>("[Insured].[DBA Name].[DBA Name].[MEMBER_CAPTION]"),
Agency = cell.Field<string>("[Agency].[Agency Name].[Agency Name].[MEMBER_CAPTION]"),
Market = cell.Field<string>("[Market].[Market Name].[Market Name].[MEMBER_CAPTION]"),
Revenue = String.Format("{0:#,##0}", cell.Field<double?>("[Measures].[Revenue]") ?? 0),
Premium = String.Format("{0:#,##0}", cell.Field<double?>("[Measures].[Premium]") ?? 0)
};
The reason you get that error is that the CellSet class in itself doesn't implement IEnumerable<T>, which is required by LINQ.
Try executing the LINQ query over the CellSet.Cells property instead. That will return a CellCollection object, which implements IEnumerable. From there you can easily convert it to an IEnumerable<T> by using the Enumerable.Cast<T> method.
AdomdCommand cmd = new AdomdCommand(commandText, conn);
CellSet cs = cmd.ExecuteCellSet();
var result = from cell in cs.Cells.Cast<Cell>()
select new
{ ... };
See also:
Retrieving Data Using the CellSet

Use enum in LinQ

need help
I have this enum which sets the PayClassNo to Direct and Indirect. I want to use this enum in my LinQ query.
Here's my scratch LinQ query:
var jDef = from jd in context.GetTable<RJVDefinition>()
select new PayrollJVDefinition
{
JVdefNo = jd.JVDefNo,
AccntCode = jd.AccntCode,
AccntDesc = jd.AccntDesc,
PayClass = enum.GetValue(jd.PayClassNo),
IsFixed = jd.IsFixed,
IsEmployee = jd.IsFixed,
IsAR = jd.IsAR,
CreatedByNo = jd.CreatedByNo,
CreatedDate = jd.CreatedDate,
ModifiedByNo = jd.ModifiedByNo,
ModifiedDate = jd.ModifiedDate
};
Need help because I'm not sure if this will work.
You could certainly do the translation in code, similar to your example (using Enum.Parse), but you don't need to. You can use the designer to set the object property type to an enumerated value. See this article for details.
You just need to parse the Enum just use something like
Enum.Parse(jb.PayClassNo, YourEnumType)

Resources