NHIBERNATE WHERE and Multiple OR clause of IQUERYOVER - c#-4.0

Hi: I tried looking at other posts. I apologize in advance if this is a duplicate post.
The sql query is something like this:
select * from ApiData where BrandID = 'SOUPBRAND' and Culture = 'de-de'
or
( BrandID = 'SOUPBRAND' and Culture = 'pt-br' and EntityType = 'contactus')
or
(BrandID = 'examplefoods')
What would the nhibernate query look like?
This is what I have so far:
var mainQuery = _session.QueryOver<ApiData>();
foreach (var brandPermission in permissions)
{
var query = _session.QueryOver<ApiData>();
if (!string.IsNullOrEmpty(brandPermission.Culture) && !string.IsNullOrEmpty(brandPermission.Publication))
{
query = query.Where(a => (a.Culture == brandPermission.Culture)
&& (a.Publication == brandPermission.Publication)); //FetchEntries(apiUser.DefaultCulture, apiUser.Publication);
}
else if (!string.IsNullOrEmpty(brandPermission.Culture))
{
query = query.Where(a => (a.Culture == brandPermission.Culture)); //FetchEntries(apiUser.DefaultCulture);
}
query = query.Where(a => a.BrandId == brandPermission.BrandId);
//Here I would like to add
// mainQuery.AddORRestriction(query);
}
Just dont know how to achieve it. Saw a link :http://www.methodicmadness.com/2012/04/extending-queryover-with-or.html but didnt help.
Thanks!

thanks to: https://www.google.com/url?q=http://ayende.com/blog/4023/nhibernate-queries-examples&usd=2&usg=AFQjCNG43MDXKhjZ9LrCVSldeZuruBSdQQ
and to: https://www.google.com/url?q=https://stackoverflow.com/questions/14478430/c-sharp-nhibernate-multiple-where-conditions-in-session-queryover&usd=2&usg=AFQjCNHRKbQz3EKGqOOh0gSV0LW2taSX-w
I got the following solution:
var mainQuery = _session.QueryOver<ApiData>();
var holdOr = Restrictions.Disjunction();
foreach (var brandPermission in permissions)
{
var query = _session.QueryOver<ApiData>();
var holdAnd = Restrictions.Conjunction();
if (!string.IsNullOrEmpty(brandPermission.Culture) && !string.IsNullOrEmpty(brandPermission.Publication))
{
holdAnd.Add(Restrictions.Eq("Culture", brandPermission.Culture));
holdAnd.Add(Restrictions.Eq("Publication", brandPermission.Publication));
}
else if (!string.IsNullOrEmpty(brandPermission.Culture))
{
holdAnd.Add(Restrictions.Eq("Culture", brandPermission.Culture));
}
holdAnd.Add(Restrictions.Eq("BrandId", brandPermission.BrandId));
holdOr.Add(holdAnd);
}
mainQuery.Where(holdOr);

Related

Access Microsoft.Storage/storageAccounts/blobServices metrics from code

I want to retrieve metrics related to Blob metric namespace from Azure Storage Account. I need to read the BlobCount value.
Initially I have tried like this:
var usedCapacityResults = await metricsClient.QueryResourceAsync(resourceId, new[] { "BlobCount1" },
new MetricsQueryOptions
{
MetricNamespace = "Blob",
Aggregations =
{
MetricAggregationType.Average
},
Granularity = TimeSpan.FromMinutes(5),
TimeRange = new QueryTimeRange(TimeSpan.FromMinutes(10))
});
if (usedCapacityResults.GetRawResponse().Status == StatusCodes.Status200OK)
{
var usedCapacityMetric = usedCapacityResults.Value.Metrics.FirstOrDefault(m => m.Name == "BlobCount" && m.Error == null);
var metricValue = usedCapacityMetric?.TimeSeries.FirstOrDefault();
if (metricValue != null && !metricValue.Values.IsNullOrEmpty())
{
var average = metricValue.Values[0].Average;
if (average != null) blobCount = (decimal)average;
}
}
But nothing gets returned.
Then I have tried to get the supported metric namespace, using this call:
GET https://management.azure.com/{resourceUri}/providers/microsoft.insights/metricNamespaces?api-version=2017-12-01-preview
and the only valid metric seems to be Microsoft.Storage/storageAccounts, that does not have the blob count metric.
Any idea how to read from code the BlobCount value?
There will be also the option to retrieve the list of containers and iterate though it to count the blobs, but this is something I want to avoid.
The working solution, with help from MS support:
This is the solution that was provided to me by MS Support team:
private async Task<decimal> GetStorageAccountBlobCount(MetricsQueryClient metricsClient, string resourceId)
{
var blobCount = (decimal)0.0;
try
{
resourceId = $"{resourceId}/blobServices/default";
var blobCountResult = await metricsClient.QueryResourceAsync(resourceId, new[] { "BlobCount" },
new MetricsQueryOptions
{
MetricNamespace = "Microsoft.Storage/storageAccounts/blobServices",
Aggregations =
{
MetricAggregationType.Average
},
Granularity = TimeSpan.FromHours(1),
TimeRange = new QueryTimeRange(TimeSpan.FromMinutes(60))
});
if (blobCountResult.GetRawResponse().Status == StatusCodes.Status200OK)
{
var blobCountMetric = blobCountResult.Value.Metrics.FirstOrDefault(m => m.Name == "BlobCount" && m.Error == null);
var metricValue = blobCountMetric?.TimeSeries.FirstOrDefault();
if (metricValue != null && !metricValue.Values.IsNullOrEmpty())
{
var average = metricValue.Values[0].Average;
if (average != null) blobCount = (decimal)average;
}
}
}
catch (Exception ex)
{
_logger.LogError($"Error on calculate blob count for {resourceId}", ex);
}
return blobCount;
}

How to change the default values when add link Sharepoint 2013

In Add Link page, is it possible to change the default values like title, address, show these links to, by using URL parameters?
According to this, it seems possible in sharepoint2010. Does anyone know whether it works in 2013??
If not, is it possible to add a link by post REST API??
This problem can be solved by the steps below.
Add a custom action. Just follow the steps here.
In my case code is as below
SP.SOD.executeFunc("callout.js", "Callout", function() {
var itemCtx = {};
itemCtx.Templates = {};
itemCtx.BaseViewID = 'Callout';
// Define the list template type
itemCtx.ListTemplateType = 101;
itemCtx.Templates.Footer = function(itemCtx) {
// context, custom action function, show the ECB menu (boolean)
return CalloutRenderFooterTemplate(itemCtx, AddCustomAction, true);
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);
});
function AddCustomAction(renderCtx, calloutActionMenu) {
// Add your custom action
calloutActionMenu.addAction(new CalloutAction({
text: "FAVORITE",
// tooltip: 'This is your custom action',
onClickCallback: function() {
CreateCustomNewQuickLink(renderCtx.CurrentItem.FileLeafRef, renderCtx.CurrentItem.FileRef);
}
}));
// Show the default document library actions
CalloutOnPostRenderTemplate(renderCtx, calloutActionMenu);
}
function CreateCustomNewQuickLink(title, url) {
var urlAddress = $(location).attr('protocol') + "//" + $(location).attr('host') + '/_Layouts/quicklinksdialogformTEST.aspx?Mode=Link' +
'&title=' + encodeURIComponent(title) +
'&url=' + encodeURIComponent(url);
ShowNewQuicklinkPopup(urlAddress, PageRefreshOnDialogClose);
}
Create a new add link page which is copied from "quicklinksdialogform.aspx". I add some javascript as below.
$(init)
function init() {
var args = new Object();
args = GetUrlParms();
if (args["title"] != undefined) {
$(".ms-long")[0].value = decodeURIComponent(args["title"]);
}
if (args["url"] != undefined) {
$(".ms-long")[1].value = decodeURIComponent(args["url"]);
}
}
function GetUrlParms() {
var args = new Object();
var query = location.search.substring(1);
var pairs = query.split("&");
for (var i = 0; i < pairs.length; i++) {
var pos = pairs[i].indexOf('=');
if (pos == -1) continue;
var argname = pairs[i].substring(0, pos);
var value = pairs[i].substring(pos + 1);
args[argname] = unescape(value);
}
return args;
}
It works like below

What is the Best Practice to update multiple fields in a Plugin

I have a plugin registered in Post operation that needs to update multiple fields in CRM using data from an XML file. Currently I am using the following code:
if (node["node1"] != null)
{
var sId = sElement.GetElementsByTagName("pId")[0].InnerText;
Guid sGUID = new Guid(sId);
sEntity["Attrib1"] = sGUID;
service.Update(sEntity);
}
if (node["node2"] != null)
{
var sMax = sElement.GetElementsByTagName("pMax")[0].InnerText;
sEntity["Attrib2"] = sMax;
service.Update(sEntity);
}
if (node["node3"] != null)
{
var sMin = sElement.GetElementsByTagName("pMin")[0].InnerText;
sEntity["Attrib3"] = sMin;
service.Update(sEntity);
}
So I am calling the service.Update each time I need to update and in the above case 3 times.
Is there a better way to accomplish what I am trying to do and call the service.Update only one time?
You can just do a single update in the end (eventually you can add a check in case none of the fields changed, to avoid a useless update):
if (node["node1"] != null)
{
var sId = sElement.GetElementsByTagName("pId")[0].InnerText;
Guid sGUID = new Guid(sId);
sEntity["Attrib1"] = sGUID;
}
if (node["node2"] != null)
{
var sMax = sElement.GetElementsByTagName("pMax")[0].InnerText;
sEntity["Attrib2"] = sMax;
}
if (node["node3"] != null)
{
var sMin = sElement.GetElementsByTagName("pMin")[0].InnerText;
sEntity["Attrib3"] = sMin;
}
service.Update(sEntity);

Servicestack ORMLite Query Multiple

I was wondering if ORMLite had a QueryMultiple solution like dapper.
My use case is in getting paged results.
return new {
Posts = conn.Select<Post>(q => q.Where(p => p.Tag == "Chris").Limit(20, 10))
TotalPosts = conn.Count<Post>(q.Where(p => p.Tag == "Chris"))
};
I also have a few other cases where I'm calculating some other stats in addition to a main query, and I'm keen to avoid multiple roundtrips.
(Probably unrelated, but I'm using PostgreSQL)
You can probably do something like this:
var bothThings = db.Exec(cmd => {
cmd.CommandText = #"
select * from TableA
select * from TableB";
var both = new BothAandB();
using (var reader = cmd.ExecuteReader())
{
both.a = reader.ConvertToList<A>();
reader.NextResult();
both.b = reader.ConvertToList<B>();
}
return both;
});
It might be possible to wrap this up in an extension method, but nothing clever is coming to mind.
You can create some helper OrmLite extensions (works in v 3.9.55.0) pretty easily that will NOT wrap the reader. It is rather easy since the methods you need are public. Here is how I did it.
public static class MultiResultReaderOrmLiteExtensions
{
public static IList CustomConvertToList<T>(this IDataReader dataReader)
{
var modelDef = ModelDefinition<T>.Definition;
var type = typeof (T);
var fieldDefs = modelDef.AllFieldDefinitionsArray;
var listInstance = typeof(List<>).MakeGenericType(type).CreateInstance();
var to = (IList)listInstance;
var indexCache = dataReader.GetIndexFieldsCache(modelDef);
while (dataReader.Read())
{
var row = type.CreateInstance();
row.PopulateWithSqlReader(dataReader, fieldDefs, indexCache);
to.Add(row);
}
return to;
}
public static Dictionary<string, int> GetIndexFieldsCache(this IDataReader reader,
ModelDefinition modelDefinition = null)
{
var cache = new Dictionary<string, int>();
if (modelDefinition != null)
{
foreach (var field in modelDefinition.IgnoredFieldDefinitions)
{
cache[field.FieldName] = -1;
}
}
for (var i = 0; i < reader.FieldCount; i++)
{
cache[reader.GetName(i)] = i;
}
return cache;
}
}
Then you can call like something like this:
using (var db = _connectionFactory.OpenDbConnection())
{
var cmd = db.api_GetSprocWithMultResults(id);
using (IDataReader reader = cmd.DbCommand.ExecuteReader())
{
meta = reader.CustomConvertToList<Element_Media_Meta>().Cast<Element_Media_Meta>().ToList();
reader.NextResult();
queues = reader.CustomConvertToList<Element_Media_ProcessQueue>().Cast<Element_Media_ProcessQueue>().ToList();
}
}

CouchDB- basic grouping question

I have a user document which has a group field. This field is an array of group ids. I would like to write a view that returns (groupid as key) -> (array of user docs as val). This mapping operation seems like a good beginning.
function(doc)
{
var type = doc.type;
var groups = doc.groups;
if(type == "user" && groups.length > 0)
{
for(var i = 0; i < groups.length; i++)
{
emit(groups[i], doc);
}
}
}
But there's obviously something very wrong with my attempt at a reduce:
function(key, values, rereduce)
{
var set = [];
var seen = [];
for(var i = 0; i < values.length; i++)
{
var _id = values[i]._id;
if(seen.indexOf(_id) == -1)
{
seen.push(_id);
set.push(values[i]);
}
}
return set;
}
I'm running CouchDB 0.10dev. Any help appreciated.
The answer to this after checking on the CouchDB IRC is that you don't need reduce for this at all. Just provide a key=groupId, something like the following:
http://localhost:5984/somedb/_design/bygroup/_view/all?key=2

Resources