I am trying to port some existing VBA code to C#. One routine controls the indentation of bullet items, and is roughly:
indentStep = 13.5
For Each parag In shp.TextRange.Paragraphs()
parag.Parent.Ruler.Levels(parag.IndentLevel).FirstMargin = indentStep * (parag.IndentLevel - 1)
parag.Parent.Ruler.Levels(parag.IndentLevel).LeftMargin = indentStep * (parag.IndentLevel)
Next parag
The code works, but appears to be spooky black magic. In particular, each time a particular ruler's margins are set ALL NINE rulers margins are actually set.
But somehow the appropriate information is being set. Unfortunately, when you do the same thing in C#, the results change. The following code has no visible effect:
const float kIndentStep = 13.5f;
foreach (PowerPoint.TextRange pg in shp.TextFrame.TextRange.Paragraphs())
{
pg.Parent.Ruler.Levels[pg.IndentLevel].FirstMargin = kIndentStep * (pg.IndentLevel - 1);
pg.Parent.Ruler.LevelS[pg.IndentLevel].LeftMargin = kIndentStep * pg.IndentLevel;
}
This appears to be a limitation/bug when automating PowerPoint from C#. I confirm it works with VBA.
I do see an effect after the code runs: it changes the first level with each run so that, at the end, the first level has the settings that should have been assigned to the last level to be processed, but none of the other levels appear to be affected, visibly. I do see a change in the values returned during code execution, but that's all.
If the code changes only one, specific level for the text frame, it works. The problem occurs only when attempting to change multiple levels.
I tried various approaches, including late-binding (PInvoke) and putting the change in a separate procedure, but the result was always the same.
Here's my last iteration
Microsoft.Office.Interop.PowerPoint.Application pptApp = (Microsoft.Office.Interop.PowerPoint.Application) System.Runtime.InteropServices.Marshal.GetActiveObject("Powerpoint.Application"); // new Microsoft.Office.Interop.PowerPoint.Application();
//Change indent level of text
const float kIndentStep = 13.5f;
Microsoft.Office.Interop.PowerPoint.Shape shp = pptApp.ActivePresentation.Slides[2].Shapes[2];
Microsoft.Office.Interop.PowerPoint.TextFrame tf = shp.TextFrame;
object oTf = tf;
int indentLevelLast = 0;
foreach (Microsoft.Office.Interop.PowerPoint.TextRange pg in tf.TextRange.Paragraphs(-1, -1))
{
int indentLevel = pg.IndentLevel;
if (indentLevel > indentLevelLast)
{
Microsoft.Office.Interop.PowerPoint.RulerLevel rl = tf.Ruler.Levels[indentLevel];
object oRl = rl;
System.Diagnostics.Debug.Print(pg.Text + ": " + indentLevel + ", " + rl.FirstMargin.ToString() + ", " + rl.LeftMargin.ToString()) ;
object fm = oRl.GetType().InvokeMember("FirstMargin", BindingFlags.SetProperty, null, oRl, new object[] {kIndentStep * (indentLevel - 1)});
//rl.FirstMargin = kIndentStep * (indentLevel - 1);
object lm = oRl.GetType().InvokeMember("LeftMargin", BindingFlags.SetProperty, null, oRl, new object[] { kIndentStep * (indentLevel) });
//rl.LeftMargin = kIndentStep * indentLevel;
indentLevelLast = indentLevel;
System.Diagnostics.Debug.Print(pg.Text + ": " + indentLevel + ", " + tf.Ruler.Levels[indentLevel].FirstMargin.ToString() + ", " + tf.Ruler.Levels[indentLevel].LeftMargin.ToString()) ;
rl = null;
}
}
FWIW neither code snippet provided in the question compiles. The VBA snippet is missing .TextFrame. The C# snippet doesn't like Parent.Ruler so I had to change it to TextFrame.Ruler.
I want to delete many managed objects, selected by fragment type. There are more then 2000 elements in it. Unfortunately I can not delete all with one function call. I have to call this function many times until I have deleted all. How can I delete a list of managed objects in a sufficient way? Not defining page size did not help...
This is my current function:
InventoryFilter filter = new InventoryFilter();
filter.byFragmentType("xy_fragment");
ManagedObjectCollection moc = inventoryApi.getManagedObjectsByFilter(filter);
int count = 0;
// max page size is 2000
for (ManagedObjectRepresentation mo : moc.get(2000).allPages()) {
if (mo.get("c8y_IsBinary") != null) {
binariesApi.deleteFile(mo.getId());
} else {
inventoryApi.delete(mo.getId());
}
LOG.debug(count + " remove: " + mo.getName() + ", " + mo.getType());
count++;
}
LOG.info("all objectes removed, count:" + count);
By calling moc.get(2000).allPages() you already obtain an iterator that queries following pages on demand as you iterate over it.
The problem you are facing is caused by deleting elements from the same list you are iterating over. You delete element from the first page, but once the second page is queried from the server it does not contain the expected elements anymore because you already deleted the first page. Now all elements are shifted forward by your page size.
You can avoid all of that by making a local copy of all elements you want to delete first:
List<ManagedObjectRepresentation> allObjects = Lists.newArrayList( moc.get(2000).allPages())
for (ManagedObjectRepresentation mo : allObjects) {
//delete here
}
There is no bulk delete allowed on the inventory API so your method of looping through the objects is the correct approach.
A bulk delete is already a dangerous tool on the other APIs but on the inventory API it would give you the potential to accidentally delete all your data with just one call (as all data associated with a managedObject is also deleted upon the deletion of the managedObject).
That is why it is not available.
I solved the problem by calling the method until no elements can be found any more. It is not nice but I have no other idea.
public synchronized void removeManagedObjects(String deviceTypeKey) {
int count = 0;
do {
count = deleteManagedObjectes(deviceTypeKey);
}while(count > 0);
}
private int deleteManagedObjectes(String deviceTypeKey) {
InventoryFilter filter = new InventoryFilter();
filter.byFragmentType("xy_fragment");
ManagedObjectCollection moc = inventoryApi.getManagedObjectsByFilter(filter);
int count = 0;
if(moc == null) {
LOG.info("ManagedObjectCollection are NULL");
return count;
}
for (ManagedObjectRepresentation mo : moc.get(2000).allPages()) {
if (mo.get("c8y_IsBinary") != null) {
binariesApi.deleteFile(mo.getId());
} else {
inventoryApi.delete(mo.getId());
}
LOG.debug(count + " remove: " + mo.getName() + ", " + mo.getType());
count++;
}
LOG.info("all objectes removed, count:" + count);
return count;
}
I'm able to execute sql statements by writing the sql codes (Insert etc) on Eclipse and it is being displayed into sql server correctly. Connection has been done. But what should I do when a user wants to add data through a GUI interface (text field) and the data need to get stored into the database automatically ??
my code in the ADD button, but i'm getting the Error: java.lang.NullPointerException ! Help please..
try {
String pid = ProductID.getText();
String sql = "insert into Products_tbl values (' " +pid + " ')";
// Running the sql query
rs = st.executeQuery(sql);
int count = 0;
while (rs.next()) {
count = count + 1;
}
if (count == 1) {
JOptionPane.showMessageDialog(null, "Welcome");
}
else if (count > 1) {
JOptionPane.showMessageDialog(null,"Duplicate User Access Denied");
}
else {
JOptionPane.showMessageDialog(null, " User Not Found ");
}
}
catch (Exception ex) {
System.out.println("Error: " + ex);
}
1- Using (' " +pid + " ')" is not safe because SQL injection may occur. Use SqlParameters instead. Please check:
https://www.w3schools.com/sql/sql_injection.asp
2- I am pretty sure something is wrong with the line: rs = st.executeQuery(sql);
Here, I bet the value of st is null. Make sure that your connection variable is defined and set correctly and you created the statement like below:
st = connection.createStatement();
You can also try executeupdate(query) instead of executequery(query) like:
int flag = st.executeUpdate(query);
Ref: https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#executeUpdate%28java.lang.String%29
3- Please use printStackTrace() method while printing the error in the catch blog, the error message would be more understandable.
System.out.println("Error: " + ex.printStackTrace());
Is there any way to programmatically understand what properties there are for a custom model in Alfresco?
For example, data dictionary in oracle helps you to find what tables are defined by which column names and column data types.
My goal is a sample code in java which extracts all custom defined content models, their attributes, their attributes data types, etc. For example my sample code should return to me that there is a custom content Model which has an integer attribute with name 'No' and a string attribute with name 'Description'. I know this is possible with DictionaryComponent, But I don't know how should I use it.
Take a look at org.alfresco.service.cmr.dictionary.DictionaryService.
will your Java-code running in-context with alfresco (as part of the /alfresco webapp) or outside?
If your running in-context, then Alfreso Java Foundation API is your choice where DictionaryService is part of. just inject the bean into your java code.
If your code is running outside of alfresco, then Alfresco REST API or CMIS is your choice.
If you're still lost, then train yourself first. Jeff wrote some good articles http://ecmarchitect.com/alfresco-developer-series & also a book.
Also a good starting point - Alfresco Developer Docs: http://docs.alfresco.com/4.2/topic/com.alfresco.enterprise.doc/concepts/dev-for-developers.html
thanks a lot of alfresian responses, My code sample is something like below:
I found the sample code from : this URL
public void GetAllAvailableDataTypes() throws IOException
{
Session session = getSession();
boolean includePropertyDefintions = true;
for (Tree t : session.getTypeDescendants(
null, // start at the top of the tree
-1, // infinite depth recursion
includePropertyDefintions // include prop defs
)) {
printTypes(t, "");
}
}
public void printTypes(Tree tree, String tab) {
ObjectType objType = (ObjectType) tree.getItem();
String type = objType.getId();
if(true)//type.endsWith("hstcase"))
{
System.out.println(tab + "TYPE:" + objType.getDisplayName() +
" (" + objType.getDescription() + ")");
//Print some of the common attributes for this type
System.out.print(tab + " Id:" + "-----"+ objType.getId() + "-----");
System.out.print(" Fileable:" + objType.isFileable());
System.out.print(" Queryable:" + objType.isQueryable());
if (objType instanceof DocumentType) {
System.out.print(" [DOC Attrs->] Versionable:" +
((DocumentType)objType).isVersionable());
System.out.println(" Content:" +
((DocumentType)objType).getContentStreamAllowed());
Map<String, org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition<?>> props = objType.getPropertyDefinitions();
Set<String> keys = props.keySet();
Collection<org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition<?>> porpsAsCollection = props.values();
for(org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition<?> p: porpsAsCollection)
{
//System.out.println(p.getDescription());
PropertyType pt = p.getPropertyType();
System.out.println("Display Name: "+ p.getDisplayName());
System.out.println("Local Name: "+ p.getLocalName());
System.out.println("Attribute Type: "+ pt.value());
}
}
System.out.println(""); // end the line
}
List<Tree> childs = tree.getChildren();
for (Tree t : childs) {
// there are more - call self for next level
printTypes(t, tab + " ");
}
}
I am trying to search an XML field within a table, This is not supported with EF.
Without using pure Ado.net is possible to have native SQL support with EF?
For .NET Framework version 4 and above: use ObjectContext.ExecuteStoreCommand() if your query returns no results, and use ObjectContext.ExecuteStoreQuery if your query returns results.
For previous .NET Framework versions, here's a sample illustrating what to do. Replace ExecuteNonQuery() as needed if your query returns results.
static void ExecuteSql(ObjectContext c, string sql)
{
var entityConnection = (System.Data.EntityClient.EntityConnection)c.Connection;
DbConnection conn = entityConnection.StoreConnection;
ConnectionState initialState = conn.State;
try
{
if (initialState != ConnectionState.Open)
conn.Open(); // open connection if not already open
using (DbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
}
}
finally
{
if (initialState != ConnectionState.Open)
conn.Close(); // only close connection if not initially open
}
}
Using Entity Framework 5.0 you can use ExecuteSqlCommand to execute multi-line/multi-command pure SQL statements. This way you won't need to provide any backing object to store the returned value since the method returns an int (the result returned by the database after executing the command).
Sample:
context.Database.ExecuteSqlCommand(#
"-- Script Date: 10/1/2012 3:34 PM - Generated by ExportSqlCe version 3.5.2.18
SET IDENTITY_INSERT [Students] ON;
INSERT INTO [Students] ([StudentId],[FirstName],[LastName],[BirthDate],[Address],[Neighborhood],[City],[State],[Phone],[MobilePhone],[Email],[Enrollment],[Gender],[Status]) VALUES (12,N'First Name',N'SecondName',{ts '1988-03-02 00:00:00.000'},N'RUA 19 A, 60',N'MORADA DO VALE',N'BARRA DO PIRAÍ',N'Rio de Janeiro',N'3346-7125',NULL,NULL,{ts '2011-06-04 21:25:26.000'},2,1);
INSERT INTO [Students] ([StudentId],[FirstName],[LastName],[BirthDate],[Address],[Neighborhood],[City],[State],[Phone],[MobilePhone],[Email],[Enrollment],[Gender],[Status]) VALUES (13,N'FirstName',N'LastName',{ts '1976-04-12 00:00:00.000'},N'RUA 201, 2231',N'RECANTO FELIZ',N'BARRA DO PIRAÍ',N'Rio de Janeiro',N'3341-6892',NULL,NULL,{ts '2011-06-04 21:38:38.000'},2,1);
");
For more on this, take a look here: Entity Framework Code First: Executing SQL files on database creation
For Entity Framework 5 use context.Database.SqlQuery.
And for Entity Framework 4 use context.ExecuteStoreQuery
the following code:
public string BuyerSequenceNumberMax(int buyerId)
{
string sequenceMaxQuery = "SELECT TOP(1) btitosal.BuyerSequenceNumber FROM BuyerTakenItemToSale btitosal " +
"WHERE btitosal.BuyerID = " + buyerId +
"ORDER BY CONVERT(INT,SUBSTRING(btitosal.BuyerSequenceNumber,7, LEN(btitosal.BuyerSequenceNumber))) DESC";
var sequenceQueryResult = context.Database.SqlQuery<string>(sequenceMaxQuery).FirstOrDefault();
string buyerSequenceNumber = string.Empty;
if (sequenceQueryResult != null)
{
buyerSequenceNumber = sequenceQueryResult.ToString();
}
return buyerSequenceNumber;
}
To return a List use the following code:
public List<PanelSerialList> PanelSerialByLocationAndStock(string locationCode, byte storeLocation, string itemCategory, string itemCapacity, byte agreementType, string packageCode)
{
string panelSerialByLocationAndStockQuery = "SELECT isws.ItemSerialNo, im.ItemModel " +
"FROM Inv_ItemMaster im " +
"INNER JOIN " +
"Inv_ItemStockWithSerialNoByLocation isws " +
" ON im.ItemCode = isws.ItemCode " +
" WHERE isws.LocationCode = '" + locationCode + "' AND " +
" isws.StoreLocation = " + storeLocation + " AND " +
" isws.IsAvailableInStore = 1 AND " +
" im.ItemCapacity = '" + itemCapacity + "' AND " +
" isws.ItemSerialNo NOT IN ( " +
" Select sp.PanelSerialNo From Special_SpecialPackagePriceForResale sp " +
" Where sp.PackageCode = '" + packageCode + "' )";
return context.Database.SqlQuery<PanelSerialList>(panelSerialByLocationAndStockQuery).ToList();
}
Keep it simple
using (var context = new MyDBEntities())
{
var m = context.ExecuteStoreQuery<MyDataObject>("Select * from Person", string.Empty);
//Do anything you wonna do with
MessageBox.Show(m.Count().ToString());
}
public class RaptorRepository<T>
where T : class
{
public RaptorRepository()
: this(new RaptorCoreEntities())
{
}
public RaptorRepository(ObjectContext repositoryContext)
{
_repositoryContext = repositoryContext ?? new RaptorCoreEntities();
_objectSet = repositoryContext.CreateObjectSet<T>();
}
private ObjectContext _repositoryContext;
private ObjectSet<T> _objectSet;
public ObjectSet<T> ObjectSet
{
get
{
return _objectSet;
}
}
public void DeleteAll()
{
_repositoryContext
.ExecuteStoreCommand("DELETE " + _objectSet.EntitySet.ElementType.Name);
}
}
So what do we say about all this in 2017? 80k consultations suggests that running a SQL request in EF is something a lot of folk want to do. But why? For what benefit?
Justin, a guru with 20 times my reputation, in the accepted answer gives us a static method that looks line for line like the equivalent ADO code. Be sure to copy it well because there are a few subtleties to not get wrong. And you're obliged to concatenate your query with your runtime parameters since there's no provision for proper parameters. So all users of this method will be constructing their SQL with string methods (fragile, untestable, sql injection), and none of them will be unit testing.
The other answers have the same faults, only moreso. SQL buried in double quotes. SQL injection opportunities liberally scattered around. Esteemed peers, this is absolutely savage behaviour. If this was C# being generated, there would be a flame war. We don't even accept generating HTML this way, but somehow its OK for SQL. I know that query parameters were not the subject of the question, but we copy and reuse what we see, and the answers here are both models and testaments to what folk are doing.
Has EF melted our brains? EF doesn't want you to use SQL, so why use EF to do SQL.
Wanting to use SQL to talk to a relational DB is a healthy, normal impulse in adults. QueryFirst shows how this could be done intelligently, your sql in .sql file, validated as you type, with intellisense for tables and columns. The C# wrapper is generated by the tool, so your queries become discoverable in code, with intellisense for your inputs and results. End to end strong typing, without ever having to worry about a type. No need to ever remember a column name, or its index. And there are numerous other benefits... The temptation to concatenate is removed. The possibility of mishandling your connections also. All your queries and the code that accesses them are continuously integration-tested against your dev DB. Schema changes in your DB pop up as compile errors in your app. We even generate a self test method in the wrapper, so you can test new versions of your app against existing production databases, rather than waiting for the phone to ring. Anyone still need convincing?
Disclaimer: I wrote QueryFirst :-)