SSMS Addin - GetHierarchy Method Is NULL - add-in

I'm writing an addin for SSMS 2014. I want to get hierarchy for search an item in ObjectExplorer.
But GetHierarchy method comes null. Does anyone have any ideas?
ObjectExplorerService objExplorerService = (ObjectExplorerService)ServiceCache.ServiceProvider.GetService(typeof(IObjectExplorerService));
MethodInfo getHierarchyMethod = objExplorerService.GetType().GetMethod("GetHierarchy", BindingFlags.Instance | BindingFlags.NonPublic);

I found answer of my question. I accessed "Object Explorer Hierarchy" with the following code.
List<IExplorerHierarchy> hierarchyList = new List<IExplorerHierarchy>();
ObjectExplorerService objExplorerService = (ObjectExplorerService)ServiceCache.ServiceProvider.GetService(typeof(IObjectExplorerService));
System.Type t = objExplorerService.GetType();
PropertyInfo getHierarchyMethod = t.GetProperty("Tree", BindingFlags.Instance | BindingFlags.NonPublic);
var value = getHierarchyMethod.GetValue(objExplorerService, null);
PropertyInfo getHierarchyMethod2s = value.GetType().GetProperty("Hierarchies", BindingFlags.Instance | BindingFlags.NonPublic);
var value2 = getHierarchyMethod2s.GetValue(value, null);
foreach (var item in (Dictionary<string, IExplorerHierarchy>)value2)
{
hierarchyList.Add(item.Value);
}

Related

Dropdownlist of values in a column of database table - MVC Entitiy Framework

I am facing issue in creating a Dropdownlist of values in a column from database table. I want to create a dropdownlist of parent category with values and key which also has null values. Below is the code for columns in my table on front end. I have tried various things like ViewBag, SelectList, MultiSelectList but no luck yet.My Dropdownlist will contain Parent Category ID and ParentCategory values. Category_Int_ID is the primary key.Kindly help me out. Thanks.
List<Category> c1 = db.Categories.ToList();
List<Category> c2 = db.Categories.ToList();
var catview = from ch in c1
join pa in c2 on ch.PARENT_CATEGORY_ID equals pa.CATEGORY_INT_ID into tab1
from pa in tab1.DefaultIfEmpty()
orderby ch.DISPLAY
select new Category
{
DISPLAY = ch.DISPLAY,
ParentCategory = (pa == null ? string.Empty : pa.DISPLAY),
DESCRIPTION = ch.DESCRIPTION,
CATEGORY_INT_ID = ch.CATEGORY_INT_ID
};
List<Category> c1 = db.Categories.ToList();
List<Category> c2 = db.Categories.ToList();
var catview = from ch in c1
join pa in c2 on ch.PARENT_CATEGORY_ID equals pa.CATEGORY_INT_ID into tab1
from pa in tab1.DefaultIfEmpty()
select new Category
{
PARENT_CATEGORY_ID = ch.PARENT_CATEGORY_ID,
ParentCategory = pa == null ? "" : pa.DISPLAY,
};
var categ11 = catview.ToList().Where(w=>w.PARENT_CATEGORY_ID !=null).Select(c => new SelectListItem()
{
Value = c.PARENT_CATEGORY_ID.ToString(),
Text = c.ParentCategory
}).Distinct();
ViewBag.Categories = categ11.ToList().Distinct();
In View
#Html.DropDownList("ParentCategoryList", (IEnumerable<SelectListItem>)ViewBag.Categories)

How do I remove the foreach from this linq code?

I'm fairly new at MVC and linq and viewmodels in particular. I managed to get a create and index views to work. The "insert" wasn't as hard as the "list".
I have this linq query:
public ActionResult Index()
{
List<BlendElVM> BEVM = new List<BlendElVM>();
var list = (from Blend in db.blends
join BlendEl in db.blendEl on Blend.ID equals BlendEl.ID
select new
{
Blend.ID, Blend.Title, Blend.TransDt, BlendEl.Comment
}).ToList();
foreach (var item in list)
{
BlendElVM o = new BlendElVM(); // ViewModel
o.Comment = item.Comment;
o.Title = item.Title;
o.TransDt = item.TransDt;
o.ID = item.ID;
BEVM.Add(o);
}
return View(BEVM);
}
What I'm not sure about is the "foreach" section. When I'm running in debug, the "list" shows up fine, but if I comment out the "foreach" I get an error - ie not expecting the model. What does the foreach do? It has to do with the database, but I don't understand the where it is using the "o" and setting the columns. I thought it would all be in one linq query. Is it possible to combine the two and eliminate the "foreach"?
var BEVM = (from blend in db.blends
join BlendEl in db.blendEl on Blend.ID equals BlendEl.ID
select new BlendELVM
{
ID = blend.ID,
Title = blend.Title,
TransDT = blend.TransDt,
comment = blendEl.Comment
}).ToList();
I believe that the foreach is needed in order to read every element in the object so in this case you have:
BlendElVM o = new BlendElVM();
So you're creating and object named " o " of the type BlendELVM and this object contains all the attributes that you declared before which are: ID, Title, TransDT, etc
When you put:
foreach (var item in list)
{
BlendElVM o = new BlendElVM(); // ViewModel
o.Comment = item.Comment;
o.Title = item.Title;
o.TransDt = item.TransDt;
o.ID = item.ID;
BEVM.Add(o);
}
You're assigning to the new object o the item that you're reading in the list and in the end adding it to the BVEM list and answering if you can combine them i will say no because at first you're declaring the query and then you're reading the items on the list and assining them to the BEVM list

linq to entities - updating tables with new values not working

The code below is updating the correct values into the OBJECT_TYPES table, but the OBJECT_ITEMS table is being overwritten but I am not sure why. Can anyone help?
var templateId = Request["id"].AsInt();
var dbcontext = new STDEntities1();
var query = dbcontext.OBJECT_TYPES.Where(o => o.ID == templateId);
var template = query.FirstOrDefault();
var newItem = new OBJECT_TYPES
{
CATEGORY_ID = template.CATEGORY_ID,
COMPANY_ID = template.COMPANY_ID,
OBJECT_NAME = "** Select A Name **",
HEIGHT = template.HEIGHT,
WIDTH = template.WIDTH,
TEMPLATE = template.ID
};
foreach (var field in template.OBJECT_ITEMS)
{
newItem.OBJECT_ITEMS.Add(field);
}
dbcontext.OBJECT_TYPES.Add(newItem);
dbcontext.SaveChanges();
this is happening because you are adding field which actually is an object that is being tracked by the dataContext/dbContext and even has an id. So the values are being overwritten.
Try creating the a new field OR try detaching the field from the context and then put the Id/Primary key to 0 and try inserting it again.

Entity Framework 4 / Linq: How to convert from DateTime to string in a query?

I have the following query:
from a in Products
select new ProductVM
{
id = a.id,
modified = a.modified.ToString()
}
Which gives me an error of:
LINQ to Entities does not recognize the method 'System.String ToString()'
method, and this method cannot be translated into a store expression.
The modified in the Products table is DateTime.
The modified in the ProductVM class is string.
Any ideas? This has to be a trivial issue.
Here's an alternative:
.Select( p -> SqlFunctions.StringConvert((double)
SqlFunctions.DatePart("m", p.modified)).Trim() + "/" +
// SqlFunctions.DateName("mm", p.modified) + "/" + MS ERROR?
SqlFunctions.DateName("dd", p.modified) + "/" +
SqlFunctions.DateName("yyyy", p.modified)
Apparently DateName("MM", ..) spells out the month name where DatePart("mm", ..) provides a numeric value, thus the StringConvert( ), but this left pads the result with spaces, thus the .Trim().
ToString() is not supported in Linq to Entities - there is a list of function helpers as part of SqlFunctions but this doesn't support Date to string conversion.
Easiest would be to first project to an anonymous type within the query and then cast to an IEnumerable by using AsEnumerable() - after that you can use ToString() because you are now using Linq to Objects for the remainder of the query expression (there's a lengthy article on this topic here).
var results = Products.Select( p => new { a.id, a.modified })
.AsEnumerable()
.Select(p => new ProductVM()
{ id = p.id,
modified = p.modified.ToString()
});
Create a new POCO with this structure (I'm assuming that the data type is DateTime):
public class UserProductVM {
...
private DateTime _modified;
public DateTime SetModified { set { _dateEvent = value; } }
public string Modified { get { return _modified.ToString("dd MMM yyyy # HH:mm:ss"); } }
...
}
Then you assign the value to SetModified, changing your code like this:
from a in Products
select new UserProductVM
{
...
SetModified = a.modified
}
Pay attention i'm using UserProductVM instead ProductVM and SetModified instead modified.
Then when you get the property Modified, the new POCO is gonna bring it as the string that you formatted.
This may not add a lot, but just in case anyone is as crazy as me, here is the full code if you need to build the expression tree for Dr. Zim's answer using DatePart/DateName including the time part as well. Obviously, for other purposes you can change Product->YourInitialType, ProductVM->YourResultType, and modified->YourProperty.
Edit (1/23/08): The SQL generated from this changed between 6.0.2 and 6.1.3. Initially, if the value were null, the SQL generated would create a null result. I considered this desirable in this case, but I can see why in other cases it would not be desired (null + "a string value" = null) and could cause output not equal to what you would prefer. I'll detail how the column output changed below, but the rub of it is that this now will output "// ::" for null values. I simply handled this output in my calling code as a special case and manually changed it back to null, but others may want to tackle adding more robust results to ensure nulls output as null. It is also worth noting that the SQL statement is very long in the new version.
ParameterExpression paramExp = Expression.Parameter(typeof(Product));
string propertyName = "modified";
Expression propertyOrField = Expression.PropertyOrField(paramExp, propertyName);
MethodInfo datePartMethod = typeof(System.Data.Entity.SqlServer.SqlFunctions).GetMethods().Where(x => x.Name == "DatePart" && x.GetParameters().Length == 2 && x.GetParameters()[1].ParameterType == typeof(DateTime?)).First();
MethodInfo dateNameMethod = typeof(System.Data.Entity.SqlServer.SqlFunctions).GetMethods().Where(x => x.Name == "DateName" && x.GetParameters().Length == 2 && x.GetParameters()[1].ParameterType == typeof(DateTime?)).First();
MethodInfo stringConvertMethod = typeof(System.Data.Entity.SqlServer.SqlFunctions).GetMethods().Where(x => x.Name == "StringConvert" && x.GetParameters().Length == 1 && x.GetParameters()[0].ParameterType == typeof(decimal?)).First();
MethodInfo stringConcatMethod = typeof(string).GetMethods().Where(x => x.Name == "Concat" && x.GetParameters().Length == 2 && x.GetParameters()[0].ParameterType == typeof(string) && x.GetParameters()[1].ParameterType == typeof(string)).First();
MethodInfo stringTrimMethod = typeof(string).GetMethods().Where(x => x.Name == "Trim" && x.GetParameters().Length == 0).First();
Type projectedType = typeof(ProductVM);
NewExpression newHolder = Expression.New(projectedType);
MemberInfo member = anonType.GetMember("modified")[0];
var monthPartExpression = Expression.Call(null, datePartMethod, Expression.Constant("mm", typeof(string)), propertyOrField);
var convertedMonthPartExpression = Expression.Call(null, stringConvertMethod, Expression.Convert(monthPartExpression, typeof(decimal?)));
var convertedDayPartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("dd", typeof(string)), propertyOrField);
var convertedYearPartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("yyyy", typeof(string)), propertyOrField);
var convertedHourPartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("hh", typeof(string)), propertyOrField);
var convertedMinutePartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("n", typeof(string)), propertyOrField);
var convertedSecondPartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("ss", typeof(string)), propertyOrField);
var allAddedExpression = Expression.Call(null, stringConcatMethod,
convertedMonthPartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant("/", typeof(string)),
Expression.Call(null, stringConcatMethod,
convertedDayPartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant("/", typeof(string)),
Expression.Call(null, stringConcatMethod,
convertedYearPartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant(" ", typeof(string)),
Expression.Call(null, stringConcatMethod,
convertedHourPartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant(":", typeof(string)),
Expression.Call(null, stringConcatMethod,
convertedMinutePartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant(":", typeof(string)),
convertedSecondPartExpression
))))))))));
var trimmedExpression = Expression.Call(allAddedExpression, stringTrimMethod, new Expression[] { });
var month = Expression.Bind(member, trimmedExpression);
MemberInitExpression memberInitExpression =
Expression.MemberInit(
newHolder,
new MemberBinding[] { month });
var lambda = Expression.Lambda<Func<Product, ProductVM>>(memberInitExpression, paramExp);

assign nullable objects for returning IQueryable

I am returning IQueryable<Customer> to the other method for some querying operations. The return method looks like:
return from cust in _dbCustList
select new Customer
{
CustomerId = cust.Customer_Id,
FirstName= cust.First_Name,
LastName= cust.Last_Name,
DOB= cust.Date_Of_Birth,
LoginTime = cust.Login_Time ?? new TimeSpan(0, 0, 0);
};
In the above result, cust.Login_Time is nullable property.
When i try to query the above result, it throws an error:
Method 'System.TimeSpan GetTimeSpan(System.Nullable`1[System.TimeSpan])' has no supported translation to SQL.
How to solve this error?
I would query into an anonymous type and then map the result to your business object in-memory:
var q = from cust in _dbCustList
select new
{
cust.Customer_Id,
cust.First_Name,
cust.Last_Name,
cust.Date_Of_Birth,
cust.Login_Time
};
return from cust in q.AsEnumerable()
select new Customer
{
CustomerId = cust.Customer_Id,
FirstName= cust.First_Name,
LastName= cust.Last_Name,
DOB= cust.Date_Of_Birth,
LoginTime = cust.Login_Time ?? TimeSpan.Zero;
};
Why do you use the null- check?
When you remove the null check the written query gets translated into a SQL query and will be executed. Now you have the result you can do any magic you want...

Resources