T4 Scaffolding - Powershell Script - t4

I am working on T4Scaffolding, i am using model to generate code, the thing is that the model, thats is POCO for DB, it must have a defined primary key else my code fails,
Here is my command
Scaffold MyScaffolder smArtistDetails -Force
Here is the .ps1 script
[T4Scaffolding.Scaffolder(Description = "Enter a description of ExtMapping here")][CmdletBinding()]
param(
[parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
[string]$ModelType,
[string]$Project,
[string]$CodeLanguage,
[string[]]$TemplateFolders,
[switch]$Force = $false
)
$mynamespace = "Sma"
$projectFor = $mynamespace + ".Infrastructure.Data"
$namespace = $projectFor # (Get-Project $projectFor).Properties.Item("DefaultNamespace").Value
$outputPath = "Mapping\" + $ModelType
Write-Host "Scaffolding $ModelType ExtMapping..."
$useModelFromProject = $mynamespace + ".Domain"
# get the modelType object from the name
$foundModelType = Get-ProjectType $ModelType -Project $useModelFromProject -BlockUi
$primaryKey = Get-PrimaryKey $ModelType -Project $useModelFromProject
$modelOutputPath = "Mapping\" + $ModelType + "Map"
Add-ProjectItemViaTemplate $modelOutputPath -Template ExtMapping `
-Model #{
Namespace = $namespace;
ModelType = [MarshalByRefObject]$foundModelType;
PrimaryKey = $primaryKey;
EntityName = $ModelType } `
-SuccessMessage "Added ExtMapping output at $projectFor" `
-TemplateFolders $TemplateFolders -Project $projectFor -CodeLanguage $CodeLanguage -Force:$Force
and here is my 74 template code
<## Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #>
<## Output Extension="cs" #>
<## import namespace="System.Collections" #>
<## import namespace="System.Collections.Generic" #>
<## import namespace="System" #>
<## import namespace="EnvDTE" #>
<## assembly name="System.ComponentModel.DataAnnotations" #>
<## assembly name="System.Core" #>
<## assembly name="System.Data.Entity" #>
<## assembly name="System.Data.Linq" #>
<## import namespace="System.Data.Linq.Mapping" #>
<## import namespace="System.Linq" #>
<## import namespace="System.Collections.Generic" #>
<## import namespace="System.Data.Objects.DataClasses" #>
<## import namespace="System.Reflection" #>
<## import namespace="System.Collections" #>
<## import namespace="System.Text.RegularExpressions" #>
using System;
using System.Collections.Generic;
using System.Text;
using FluentNHibernate.Mapping;
using Sma.Domain.Model;
<#
var modelType = (CodeType)Model.ModelType;
var modelName = modelType.Name;
var properties = modelType.VisibleMembers().OfType<CodeProperty>();
var primaryKeyProperty = modelType.VisibleMembers().OfType<CodeProperty>().Single(x => x.Name == Model.PrimaryKey);
#>
namespace <#= Model.Namespace #>.Mapping
{
public class <#= Model.EntityName #>Map : ClassMap<<#= Model.EntityName #>>
{
public <#= Model.EntityName #>Map() {
Table("<#= Model.EntityName #>");
LazyLoad();
<# var type = "";
var typeName = "";
foreach (var property in properties)
{
type = GetType(property.Type);
typeName = GetTypeName(property.Type);
if( isType(type) )
{
if( Model.PrimaryKey == property.Name )
{
#>
Id(x => x.<#= property.Name #>).GeneratedBy.Identity().Column("<#= property.Name #>");
<#
}
else
{
#>
Map(x=>x.<#= property.Name #>).Column("<#= property.Name #>");
<#}
}
else
{
#>
References(x=>x.<#= property.Name #>);
<#
}
}
#> }
}
}
<#+
string GetType(EnvDTE.CodeTypeRef type)
{
string str = "";
if (type.UnderlyingTypeIs<byte>())
str = "byte";
else if (type.UnderlyingTypeIs<sbyte>())
str = "sbyte";
else if (type.UnderlyingTypeIs<int>())
str = "int";
else if (type.UnderlyingTypeIs<uint>())
str = "uint";
else if (type.UnderlyingTypeIs<short>())
str = "short";
else if (type.UnderlyingTypeIs<ushort>())
str = "ushort";
else if (type.UnderlyingTypeIs<DateTime>())
str = "DateTime";
else if (type.UnderlyingTypeIs<long>())
str = "long";
else if (type.UnderlyingTypeIs<ulong>())
str = "ulong";
else if (type.UnderlyingTypeIs<double>())
str = "double";
else if (type.UnderlyingTypeIs<bool>())
str = "bool";
else if (type.UnderlyingTypeIs<string>())
str = "string";
else if (type.UnderlyingTypeIs<decimal>())
str = "decimal";
else
str = type.AsFullName.ToString();
return str;
}
string GetTypeName(EnvDTE.CodeTypeRef type)
{
string str = type.AsFullName.ToString();
return str;
}
bool isType(string _type)
{
if( _type == "byte" ) return true;
else if( _type == "sbyte" ) return true;
else if( _type == "int" ) return true;
else if( _type == "uint" ) return true;
else if( _type == "short" ) return true;
else if( _type == "ushort" ) return true;
else if( _type == "DateTime" ) return true;
else if( _type == "long" ) return true;
else if( _type == "ulong" ) return true;
else if( _type == "double" ) return true;
else if( _type == "bool" ) return true;
else if( _type == "string" ) return true;
else if( _type == "decimal" ) return true;
return false;
}
#>
what to do.. If the primary key is not found i want to follow a different output\genration method.
Should i switch from script to a different template, if yes then How
or Should i handle this in this template, if yes then how.

I would check if the PK was found in the PS, and if not call another template... Personally I would force all the classes in the model to inherit a abstract base class that already has a primary key. That way this will never be an issue. But then again, your purpose might be something I do not know of...

Related

Antlr generated code invalid after upgrading from 3.2 to 3.5.2

I'm newbie in antlr
Because of a migration to java 8 , i must migrate an antlrv3 code from 3.2 to 3.5.2.
I have nothing changed in the antlr grammar who work perfectly with the version 3.2 and java 7 (target java 6)
With the version 3.5.2 of antlr maven generate compilation error like:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile (default-compile) on project ccff-sql2xpath: Compilation failure: Compilation failure:
[ERROR] /C:/ProjectSVN/JSR170/ccff-sql2xpath/target/generated-sources/antlr3/sql2xpath/query/compiler/TParser.java:[262,73] cannot find symbol
[ERROR] symbol: variable props
[ERROR] location: variable p of type org.antlr.runtime.ParserRuleReturnScope
I think that something has changed in the way of antlr v3.5.2 generate the code because i have more than 77600 lines with this one and 'only' 3181 lines with the older version of antlr in the TParser.java generated file
Can you help me ?
Here is the parser grammar:
parser grammar TParser;
options {
language = Java;
output = AST;
superClass = AbstractTParser;
tokenVocab = TLexer;
}
#header {
package sql2xpath.query.compiler;
import sql2xpath.query.xpath.XPathException;
import sql2xpath.query.xpath.constraint.TemporaryPathConstraint;
}
//=============================================================================
query
: s=select (f=from)? (w=where)? (o=orderby)? EOF;
//=============================================================================
select
: SELECT^ p=proplist {
for (String o: ((List<String>) p.props)) {
composer.getColumnSpecifier().addProperty(o);
}
};
//=============================================================================
from returns[String res = "unknown"]
: FROM^ n=ntlist {
if (n.nodetypes.size() > 1)
throw new XPathException("Unable to deal with joined tables in FROM clause");
composer.getPathConstraint().setTypeName(toCompactStringTree(n.nodetypes.get(0)));
};
//=============================================================================
where returns[String res = "unknown"]
: WHERE^ o=orexpression[true] {
if (o.res != null) {
// System.out.println("add constraint: " + o.res);
composer.getPropertyConstraint().addConstraint(o.res);
}
};
//=============================================================================
orderby returns[String res = "unknown"]
: (ORDER BY)^ p=propname d=(DESC | ASC)? {
if (d == null)
composer.getOrderingSpecifier().addProperty(p.res, null);
else if (d.getType() == ASC)
composer.getOrderingSpecifier().addProperty(p.res, "ascending");
else
composer.getOrderingSpecifier().addProperty(p.res, "descending");
} (COMA q=propname e=(DESC | ASC)? {
if (e == null)
composer.getOrderingSpecifier().addProperty(q.res, null);
else if (e.getType() == ASC)
composer.getOrderingSpecifier().addProperty(q.res, "ascending");
else
composer.getOrderingSpecifier().addProperty(q.res, "descending");
})* ;
//=============================================================================
proplist returns[Object props]
#init{
List<String> l = new ArrayList<String>();
}
: a=propname { l.add(a.res); } (COMA b=propname { l.add(b.res); })* { $props = l; };
//=============================================================================
ntlist returns[List nodetypes]
: c+=complexpropname (COMA c+=complexpropname)* { $nodetypes = $c; };
//=============================================================================
orexpression[boolean b] returns[String res = null]
#init{
List<String> l = new ArrayList<String>();
List<Object> p = new ArrayList<Object>();
}
: a=andexpression[b] {
p.addAll(((List<Object>)(((Object []) a.res)[1])));
l.add((String)(((Object []) a.res)[0]));
} (OR^ c=andexpression[b] {
p.addAll(((List<Object>)(((Object []) c.res)[1])));
l.add((String)(((Object []) c.res)[0]));
})* {
StringBuffer sb = new StringBuffer();
for (String s: l)
if (s!=null)
sb.append(s + " or ");
if (sb.length() > 0)
$res = sb.substring(0,sb.length()-4);
if (p.size() > 2)
throw new XPathException("Unable to deal with more than two path constraints");
else if (p.size() == 2) {
if (!$b)
throw new XPathException("Cannot deal with negated or clauses");
TemporaryPathConstraint pc1 = (TemporaryPathConstraint) p.get(0);
TemporaryPathConstraint pc2 = (TemporaryPathConstraint) p.get(1);
//LOGGER.debug("Found or-ed constraints on jcr:path = " + pc1.path + " OR " + pc2.path);
if (pc1.b && pc2.b) {
composer.getPathConstraint().orConstraint(pc1.path, pc2.path);
} else
throw new XPathException("Only positive path constraints can be in the same or clause");
}else if (p.size() == 1) {
if (!$b)
throw new XPathException("Cannot deal with single negated path constraint");
TemporaryPathConstraint pc1 = (TemporaryPathConstraint) p.get(0);
//LOGGER.debug("Found single constraint on jcr:path = " + pc1.path);
if (pc1.b) {
composer.getPathConstraint().singleConstraint(pc1.path);
} else {
throw new XPathException("Cannot deal with negative single path constraints");
}
}
};
//=============================================================================
andexpression[boolean b] returns[Object res = null]
#init{
List<String> l = new ArrayList<String>();
List<Object> p = new ArrayList<Object>();
String k = null;
}
: a=notexpression[b] { if (a.res instanceof TemporaryPathConstraint) p.add(a.res); else l.add((String)a.res); } (AND^ c=notexpression[b] { if (c.res instanceof TemporaryPathConstr
StringBuffer sb = new StringBuffer();
for (String s: l)
if (s!=null)
sb.append(s + " and ");
if (sb.length() > 0)
k = sb.substring(0,sb.length()-5);
if (p.size() > 2)
throw new XPathException("Unable to deal with more than two path constraints");
else if (p.size() == 2) {
if (!$b)
throw new XPathException("Cannot deal with negated and clauses");
TemporaryPathConstraint pc1 = (TemporaryPathConstraint) p.get(0);
TemporaryPathConstraint pc2 = (TemporaryPathConstraint) p.get(1);
//LOGGER.debug("Found and-ed constraints on jcr:path = " + pc1.path + " AND " + pc2.path);
if (pc1.b && !pc2.b) {
composer.getPathConstraint().andNotConstraint(pc1.path, pc2.path);
} else if (pc2.b && !pc1.b) {
composer.getPathConstraint().andNotConstraint(pc2.path, pc1.path);
} else
throw new XPathException("Only one positive and one negative path constraint can be in the same and clause");
p.clear();
}
$res = new Object [] {k, p};
};
//=============================================================================
notexpression[boolean b] returns[Object res = null]
: NOT^ d=containsexpression[false] { if (!$b) throw new XPathException("Impossible to parse nested NOT operators"); $res = d.res;}
| c=containsexpression[b] {$res = c.res; };
//=============================================================================
containsexpression[boolean b] returns[Object res = null]
: c=containsfun[b] { $res = c.res; }
| v=value IN p=propname { $res = composer.getPropertyConstraint().getComparingConstraint(p.res, "=", v.res, b); }
| o=operatorexpression[b] { $res = o.res; };
//=============================================================================
operatorexpression[boolean b] returns[Object res = null]
: p=propname o=op v=value {
if ("jcr:path".equals(p.res))
if (!"=".equals(o.res))
throw new XPathException("Impossible to use other operator than \"=\" or \"LIKE\" with jcr:xpath property");
else {
TemporaryPathConstraint tpc = new TemporaryPathConstraint(TemporaryPathConstraint.EQUAL);
tpc.path = v.res;
tpc.b = $b;
$res = tpc;
}
//composer.getPathConstraint().addConstraintAndProcess(v.res, b, false);
else
$res = composer.getPropertyConstraint().getComparingConstraint(p.res, o.res, v.res, b);
}
| p=propname IS NULL { $res = composer.getPropertyConstraint().getIsNullConstraint(p.res, b); }
| p=propname IS NOT NULL { $res = composer.getPropertyConstraint().getIsNotNullConstraint(p.res, b); }
| l=like[b] { $res = l.res; }
| t=parentexpression[b] { $res = t.res; };
//=============================================================================
op returns[String res = "unknown"]
: EQ { $res = "="; }
| NEQ { $res = "!="; }
| LEQ { $res = "<="; }
| LES { $res = "<"; }
| GEQ { $res = ">="; }
| GRE { $res = ">"; };
//=============================================================================
parentexpression[boolean b] returns[String res = "unknown"]
: LEFT_PAREN o=orexpression[b] RIGHT_PAREN { $res = "(" + o.res + ")"; };
//=============================================================================
propname returns[String res = "unknown"]
: QUOT c=complexpropname QUOT { $res = $c.res; }
| c=complexpropname { $res = $c.res; };
//=============================================================================
complexpropname returns[String res = "unknown"]
: a=simplepropname (DOT b=simplepropname)? {$res = a.res; if (b != null) $res += "." + b.res;};
//=============================================================================
simplepropname returns[String res = "unknown"]
: a=identifier (COLON b=identifier)? {$res = a.res; if (b != null) $res += ":" + b.res;};
//=============================================================================
identifier returns[String res = "unknown"]
: nq=NonQuotedIdentifier { $res = $nq.getText(); }
| q=QuotedIdentifier { $res = q.getText(); }
| l=Letter { $res = l.getText(); }
| STAR { $res = "*"; };
//=============================================================================
value returns[String res = "value"]
: x=complexpropname { $res = x.res; }
| c=constant { $res = c.res; };
//=============================================================================
like[boolean b] returns[Object res = null]
: p=propname LIKE e=expression (c = escape)? {
if ("jcr:path".equals(p.res)) {
TemporaryPathConstraint tpc = new TemporaryPathConstraint(TemporaryPathConstraint.LIKE);
tpc.path = e.res;
tpc.b = $b;
$res = tpc;
// composer.getPathConstraint().addConstraintAndProcess(((c == null) ? e.res : e.res.replaceAll(c.res, "\\" + c.res)), $b, false);
} else
$res = composer.getPropertyConstraint().getLikeConstraint(p.res, ((c == null) ? e.res : e.res.replaceAll(c.res, "\\" + c.res)), $b);
};
//=============================================================================
escape returns[String res = "escape"]
: ESCAPE e=expression { $res = e.res; };
//=============================================================================
expression returns[String res = "expression"]
: (u=unaryOperator)? c=constant { $res = ((u!=null)?u.res:"") + c.res; };
//=============================================================================
unaryOperator returns[String res = "unaryOperator"]
: MINUS { $res = "-"; };
//=============================================================================
constant returns[String res = "constant"]
: Number { $res = $Number.getText(); }
| NULL { $res = $NULL.getText(); }
| s=stringLiteral { $res = s.res; }
| Currency { $res = $Currency.getText(); }
| ODBCDateTime { $res = $ODBCDateTime.getText(); };
//=============================================================================
stringLiteral returns[String res = "stringLiteral"]
: UnicodeStringLiteral { $res = $UnicodeStringLiteral.getText(); }
| ASCIIStringLiteral { $res = $ASCIIStringLiteral.getText(); };
//=============================================================================
containsfun[boolean b] returns[String res = "containsfun"]
: CONTAINS_FUN c=containscope COMA e=expression RIGHT_PAREN {
$res = composer.getPropertyConstraint().getContainsConstraint(c.res, e.res, b);
};
//=============================================================================
containscope returns[String res = "containscope"]
: c=complexpropname { $res = c.res; }
| DOT { $res = "."; };
Here is the code of the method where is the error:
// $ANTLR start "select"
// be\\fgov\\minfin\\ccff\\jcr2\\sql2xpath\\query\\compiler\\TParser.g:27:4: select : SELECT ^p= proplist ;
public final TParser.select_return select() throws RecognitionException {
TParser.select_return retval = new TParser.select_return();
retval.start = input.LT(1);
Object root_0 = null;
Token SELECT2=null;
ParserRuleReturnScope p =null;
Object SELECT2_tree=null;
try {
// sql2xpath\\query\\compiler\\TParser.g:28:5: ( SELECT ^p= proplist )
// sql2xpath\\query\\compiler\\TParser.g:28:7: SELECT ^p= proplist
{
root_0 = (Object)adaptor.nil();
SELECT2=(Token)match(input,SELECT,FOLLOW_SELECT_in_select186);
SELECT2_tree = (Object)adaptor.create(SELECT2);
root_0 = (Object)adaptor.becomeRoot(SELECT2_tree, root_0);
pushFollow(FOLLOW_proplist_in_select191);
p=proplist();
state._fsp--;
adaptor.addChild(root_0, p.getTree());
for (String o: ((List<String>) p.props)) { // <=====[ERROR]
composer.getColumnSpecifier().addProperty(o);
}
}
retval.stop = input.LT(-1);
retval.tree = (Object)adaptor.rulePostProcessing(root_0);
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
}
catch (RecognitionException re) {
reportError(re);
recover(input,re);
retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
}
finally {
// do for sure before leaving
}
return retval;
}
// $ANTLR end "select"
I think I understood the compilation error:
The p property of type ParserRuleReturnScope is initialized with a method that returns a class of type proplist_return and extends the class ParserRuleReturnScope.
ParserRuleReturnScope p =null;
...
p=proplist(); // (proplist_return extend ParserRuleReturnScope)
...
for (String o: ((List<String>) p.props)) { // <=====[COMPILATION ERROR]
Because the class prolist_return is a child of ParserRuleReturnScope, p must be cast before searching for properties included in the child class, here the props property
like this:
proplist_return castP = (proplist_return) p;
for (String o: ((List<String>) castP.props)) {
With version 3.2, the plugin generates an error free code. with version 3.5.2, it generates these errors!
I understand the cause of the compilation error.
In fact version 3.5.2 of ANTLR is stricter, and in the action part of my rule 'select' in the grammar antlr, I forgot to reference the variable p and add a $ before. That's why the generator does not cast my class (see comment above)
the wrong grammar is:
select
: SELECT^ p=proplist {
for (String o: ((List<String>) p.props)) {
composer.getColumnSpecifier().addProperty(o);
}
};
So the solution is:
select
: SELECT^ p=proplist {
for (String o: ((List<String>) $p.props)) {
composer.getColumnSpecifier().addProperty(o);
}
};

How to simply print both variables' names & values in MQL4?

I hope to write a function PrintVars() that is able to print the variables altogether with their names. e.g.:
int var1 = 1;
bool var2 = True;
int var3 = 2;
PrintVars( var1, var2, var3 );
The expected output to the console is:
var1=1
var2=true
var3=2
The difficulty here is to
Get the variable name;
passing parameters of various types to the function.
Is there a way to achieve 1 and 2?
Neither 1) nor 2)
as MQL4 is a strong typed, compiled language.
Other possibilities to escape from this language syntax constraint ?
One may design a middle-ware tool for doing this, either locally, inside MQL4 or externally, via a messaging based distributed system ( having a remote terminal window ).
MQL4-based polymorphism is somewhat easier with class-based calling interface, while the efforts would be immense if such module ought be elaborated for some production grade deployment.
Somewhat clumsy sketch of the approach follows:
- create your vars as a properly configured polymorphic instance of aNamedVARIABLE class
- create a printing function, receiving a long list ( or a placeholder ( string &NameValueARRAY[] ) for a string array[][2]; initialised with "" and pre-filled with Name-Value pairs by .getName2PRINT(), resp. .getValue2PRINT() public methods ) of string variables to print, unless they are left as just initialised == ""
string printFun( const string N1 = "",
const string V1 = "",
const string N2 = "",
const string V2 = "",
...
..
.
){ string aPrintSTRING = "";
aPrintSTRING += ( ( N1 != "" ) ? ( N1 + " = " + V1 ) : "" );
aPrintSTRING += ( ( N2 != "" ) ? ( N2 + " = " + V2 ) : "" );
aPrintSTRING += ( ( N3 != "" ) ? ( N3 + " = " + V3 ) : "" );
...
..
.
return( aPrintSTRING );
}
...
..
.
print( printFun( aNamedVAR1.getName2PRINT(), aNamedVAR1.getValue2PRINT(),
aNamedVAR2.getName2PRINT(), aNamedVAR2.getValue2PRINT(),
aNamedVAR3.getName2PRINT(), aNamedVAR3.getValue2PRINT(),
aNamedVAR4.getName2PRINT(), aNamedVAR4.getValue2PRINT()
)
);
class aNamedVARIABLE{
private:
string aNameAsSTRING = "";
bool aValueAsBOOL = False;
bool aValueAsBOOL_[] = {};
int aValueAsINT = EMPTY_VALUE;
int aValueAsINT_[] = {};
string aValueAsSTR = "";
string aValueAsSTR_[] = {};
...
..
.
isBoolean = False;
isInteger = False;
isShort = False;
isUint = False;
isUchar = False;
isChar = False;
isString = False;
isDouble = False;
isDatetime = False;
isColor = False;
isClass = False;
isEnum = False;
isStruct = False;
isBooleanArr = False;
isIntegerArr = False;
isUintArr = False;
isShortArr = False;
isUintArr = False;
isUcharArr = False;
isDoubleArr = False;
isDatetimeArr = False;
isColorArr = False;
public:
aNamedVARIABLE() {}; // default constructor
aNamedVARIABLE( const string aName,
const bool aBool ){ aNamedVARIABLE::setBool( aBool );
aNamedVARIABLE::setName( aName );
}
aNamedVARIABLE( const string aName,
const int anInt ){ aNamedVARIABLE::setInt( anInt );
aNamedVARIABLE::setName( aName );
}
...
..
.
getName2PRINT() { return( this.aNameAsSTRING );
}
getValue2PRINT() { if ( this.isBoolean ) return( this.aValueAsBOOL ? "True" : "False" );
if ( this.isInteger ) return( str( this.aValueAsINT ) );
...
..
.
}
}

Linq to Entities Where Or clause

Have read other responses to similar issuebut I can not use PredicateBuilder, or copy its source. I'm trying what I've read here:
<https://blogs.msdn.microsoft.com/meek/2008/05/02/linq-to-entities-combining-predicates/
but as I'm newb, am having trouble with translating what I'm reading to what I'm applying. I have created a L2E query, and trying to append a series of OR clauses onto the WHERE:
So as simplified snippet (this one will be AND'd with the previously already defined WHERE clause):
if (firstParm == "realtor")
query = query.Where(x=> x.A == "realtor");
Now trying to OR:
if (secondParm == "clown")
// how to add this one as an OR to the above query:
query = query.OR(x=> x.fool == "clown");
I understand this can be done also with Union, but not clear on the syntax:
query = query.Union(x=> x.fool == "clown"); // ??
I've also referenced:
Combining two expressions (Expression<Func<T, bool>>)
Unable to create a compound Expression<Func<string, bool>> from a set of expressions
but again, I am new to LINQ and especially Expression Trees, so need more fillin.
There are two ways to generate expressions.
Use the compiler to do it.
Expression<Func<Person, bool>> = p => p.LastName.Contains("A");
Limitations: The only expressions that can be generated this way are instances of LambdaExpression. Also, it is rather complicated to extract parts of the expression and combine with other parts.
Use the static methods at System.Linq.Expressions.Expression.
In order to generate dynamic expressions, you can either choose between different compiler-generated expressions:
// using Record and Records as a placeholder for the actual record type and DbSet property
Expression<Func<Record,bool>> expr;
if (firstParam == "realtor") {
if (secondParam == "clown") {
expr = x => x.A == "realtor" || x.fool == "clown";
} else {
expr = x => x.A == "realtor";
}
} else {
if (secondParam == "clown") {
expr = x => x.fool="clown";
} else {
expr = x => false;
}
}
var ctx = new MyDbContext();
var qry = ctx.Records.Where(expr).Select(x => new {x.A, x.fool});
Or, you can dynamically create the expression using the static methods:
(Add using System.Linq.Expressions; and using static System.Linq.Expressions.Expression; to the top of the file.)
Expression expr;
var parameter = Parameter(typeof(Record));
if (firstParam == "realtor") {
expr = Equals(
MakeMemberAccess(parameter, typeof(Record).GetProperty("A")),
Constant("realtor")
);
}
if (secondParam == "clown") {
var exprClown = Equals(
MakeMemberAccess(parameter, typeof(Record).GetProperty("fool")),
Constant("clown")
);
if (expr == null) {
expr = exprClown;
} else {
expr = Or(expr, exprClown);
}
}
var lambda = Lambda<Func<Record,bool>>(expr, new [] {parameter});
var ctx = new MyDbContext();
var qry = ctx.Records.Where(lambda).Select(x => new {x.A, x.fool});
Given a query with a type unknown at compile time, so any variable referring to it must be IQueryable only, and not IQueryable<T>:
IQueryable qry = ctx.GetQuery(); //dynamically built query here
var parameter = Parameter(qry.ElementType);
if (firstParam == "realtor") {
expr = Equals(
MakeMemberAccess(parameter, qry.ElementType.GetProperty("A")),
Constant("realtor")
);
}
if (secondParam == "clown") {
var exprClown = Equals(
MakeMemberAccess(parameter, qry.ElementType.GetProperty("fool")),
Constant("clown")
);
if (expr == null) {
expr = exprClown;
} else {
expr = Or(expr, exprClown);
}
}
var lambda = Lambda(expr, new [] {parameter});
//Since we don't have access to the TSource type to be used by the Where method, we have
//to invoke Where using reflection.
//There are two overloads of Queryable.Where; we need the one where the generic argument
//is Expression<Func<TSource,bool>>, not Expression<Func<TSource,int,bool>>
var miWhere = typeof(Queryable).GetMethods().Single(mi => {
mi.Name == "Where" &&
mi.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments().Length == 2
});
qry = miWhere.Invoke(null, new [] {qry, lambda});
For Or you can try
if (secondParm == "clown")
{
query = query.Where(x=> x.fool == "clown" || x.fool==x.fool);
}
OR
if (secondParm == "clown")
{
query = query.Where(x=> x.fool == "clown" || true );
}

How to let XPathExtractor extract xml element only if Http response code is 200?

In my JMeter test plan, I have a HttpRequest, I want to extract the link from its response only if the response code is 200.
I can add an XPathExtractor post processor under HttpRequest and it works.
But I want to have an IfCondition first so that the extractor won't try to work on invalid content. But the IfController can't be added as a postprocessor.
Maybe I can have a BeanShell sampler to do it but I don't know how to use XPathExtractor in BeanShell.
"Short and easy" way - use an additional Sampler
Add If Controller after the HTTP Request
Use ${JMeterThread.last_sample_ok} as "Condition"
Put Beanshell Sampler under the If Controller
Use the following code in Beanshell Sampler "Script" area:
SampleResult.setResponseData(ctx.getPreviousResult().getResponseData());
Put XPath Extractor as a child of the Beanshell Sampler
The above Beanshell script will return the same response as preceding HTTP Request sampler
"Long and hard" way - extract XPath directly in Beanshell.
Put Beanshell PostProcessor instead of XPath Extractor
Use the following script as a reference:
import org.apache.jmeter.util.PropertiesBasedPrefixResolver;
import org.apache.jmeter.util.XPathUtil;
import org.apache.xpath.XPathAPI;
import org.apache.xpath.objects.XObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
InputStream in = new ByteArrayInputStream(prev.getResponseData());
boolean useNameSpace = false;
boolean isTolerant = true;
boolean isQuiet = true;
boolean showWarnings = true;
boolean reportErrors = true;
boolean isXML = false;
boolean isDownloadDTDs = false;
if (prev.isResponseCodeOK()) {
InputStream in = new ByteArrayInputStream(prev.getResponseData());
boolean useNameSpace = false;
boolean isTolerant = true;
boolean isQuiet = true;
boolean showWarnings = true;
boolean reportErrors = true;
boolean isXML = false;
boolean isDownloadDTDs = false;
String query = "//a[text()='JMeter FAQ (Wiki)']";
List matchStrings = new ArrayList();
//matchStrings.add("-1");
boolean returnFragment = false;
Document doc = XPathUtil.makeDocument(in, false, false, useNameSpace, isTolerant, isQuiet, showWarnings, reportErrors
, isXML, isDownloadDTDs);
String val = null;
XObject xObject = XPathAPI.eval(doc, query, new PropertiesBasedPrefixResolver(doc.getDocumentElement());
int objectType = xObject.getType();
if (objectType == xObject.CLASS_NODESET) {
NodeList matches = xObject.nodelist();
int length = matches.getLength();
for (int i = 0; i < length; ++i) {
Node match = matches.item(i);
if (match instanceof Element) {
if (returnFragment) {
StringWriter sw = new StringWriter();
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.transform(new DOMSource(match), new StreamResult(sw));
val = sw.toString();
} else {
Node firstChild = match.getFirstChild();
if (firstChild != null) {
val = firstChild.getNodeValue();
} else {
val = match.getNodeValue();
}
}
} else {
val = match.getNodeValue();
}
matchStrings.add(val);
}
} else if (objectType != xObject.CLASS_NULL && objectType != xObject.CLASS_UNKNOWN && objectType != xObject.CLASS_UNRESOLVEDVARIABLE) {
val = xObject.toString();
matchStrings.add(val);
} else {
log.warn("Unexpected object type: " + xObject.getTypeString() + " returned for: " + query);
}
for (String match : matchStrings) {
log.info("Match -----> " + match);
}
}
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for more information on using Beanshell in JMeter scripts

Skip first column and get distinct from other columns

I need to select distinct rows from Textfile display below.
TextFile
123| one| two| three <br/>
124| one| two| four <br/>
125| one |two| three <br/>
Output should like this
123| one| two| three <br/>
124| one| two| four <br/>
OR
124| one| two| four <br/>
125| one |two| three <br/>
I am using this code to work out this problem
var readfile = File.ReadAllLines(" text file location ");
var spiltfile = (from f in readfile
let line = f.Split('|')
let y = line.Skip(1)
select (from str in y
select str).FirstOrDefault()).Distinct()
Thanks
The unclear spacing in the question doesn't help (especially around the |two|, which has different spacing than the rest, implying we need to use trimming), but here's some custom LINQ methods that do the job. I've used the anon-type purely as a simple way of flattening out the inconsistent spacing (I could also have rebuilt a string, but it seemed unnecessary)
Note that without the odd spacing, this can be simply:
var qry = ReadLines("foo.txt")
.DistinctBy(line => line.Substring(line.IndexOf('|')));
Full code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
static class Program
{
static void Main()
{
var qry = (from line in ReadLines("foo.txt")
let parts = line.Split('|')
select new
{
Line = line,
Key = new
{
A = parts[1].Trim(),
B = parts[2].Trim(),
C = parts[3].Trim()
}
}).DistinctBy(row => row.Key)
.Select(row => row.Line);
foreach (var line in qry)
{
Console.WriteLine(line);
}
}
static IEnumerable<TSource> DistinctBy<TSource, TValue>(
this IEnumerable<TSource> source,
Func<TSource, TValue> selector)
{
var found = new HashSet<TValue>();
foreach (var item in source)
{
if (found.Add(selector(item))) yield return item;
}
}
static IEnumerable<string> ReadLines(string path)
{
using (var reader = File.OpenText(path))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
}
Check out this, this will do what you want to do
static void Main(string[] args)
{
string[] readfile = System.IO.File.ReadAllLines(#"D:\1.txt");
var strList = readfile.Select(x => x.Split('|')).ToList();
IEnumerable<string[]> noduplicates =strList.Distinct(new StringComparer());
foreach (var res in noduplicates)
Console.WriteLine(res[0] + "|" + res[1] + "|" + res[2] + "|" + res[3]);
}
And implement the IEqualityComparer this way
class StringComparer : IEqualityComparer<string[]>
{
public bool Equals(string[] x, string[] y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x[1].Trim() == y[1].Trim() && x[2].Trim() == y[2].Trim() && x[3].Trim() == y[3].Trim() ;
}
public int GetHashCode(string[] data)
{
if (Object.ReferenceEquals(data, null)) return 0;
int hash1 = data[1] == null ? 0 : data[1].Trim().GetHashCode();
int hash2 = data[2] == null ? 0 : data[2].Trim().GetHashCode();
int hash3 = data[3] == null ? 0 : data[3].Trim().GetHashCode();
return hash1 ^ hash2 * hash3;
}
}
It will give u the output as you expected.

Resources