LINQPad - Control column order when rendering IEnumerable<MyObject>? - linqpad

I've written a query that returns IEnumerable<Item>, where the Item class has several different members:
public class Item
{
public string Name { get; private set; }
public string Type { get; private set; }
public IEnumerable<Property> Properties;
public IEnumerable<Item> Items;
public Item(XElement itemElement)
{
Name = itemElement.Attribute("name").Value;
Type = itemElement.Attribute("type").Value;
Properties = from property in itemElement.Elements("Property")
select new Property(property);
Items = from item in itemElement.Elements("Item")
select new Item(item);
}
}
I don't like the order that LINQPad has chosen for assigning the Item properties to columns in the result tables. I want the columns to appear in the order Name, Type, Properties, Items, but the LINQPad default is showing Properties, Items, Name, Type. Is there a way to hint to LINQPad what order the property columns should be in?

I would still like to know if
there is a way to override the LINQPad Dump() column order in
situations where I don't control the declaration order for
IEnumerable<FooObject>.
Providing you can change you Item class, you can do this by implementing ICustomMemberProvider (see http://www.linqpad.net/FAQ.aspx#extensibility)
eg
public class Item : LINQPad.ICustomMemberProvider
{
...
IEnumerable<string> ICustomMemberProvider.GetNames()
{
return new [] { "Name", "Type", "Properties", "Items" };
}
IEnumerable<Type> ICustomMemberProvider.GetTypes ()
{
return new [] { typeof (string), typeof(string) , typeof(IEnumerable<Item>), typeof(IEnumerable<Property>) };
}
IEnumerable<object> ICustomMemberProvider.GetValues ()
{
return new object [] { this.Name, this.Type, this.Properties, this.Items };
}
}

The LINQPad sort order described in the question was occurring because Name and Type were C# object properties, but the Properties member and Items member were actually C# object fields.
It seems LINQPad displays object fields before properties by default.
I added auto-implemented properties to the Properties member and Items member:
public string Name { get; private set; }
public string Type { get; private set; }
public IEnumerable<Property> Properties { get; private set; }
public IEnumerable<Item> Items { get; private set; }
After making this change, the LINQPad column order matched the member declaration order in the class, which is what I originally wanted.
But, I will leave this question here and not accept my own answer, because I would still like to know if there is a way to override the LINQPad Dump() column order in situations where I don't control the declaration order for IEnumerable<FooObject>.

Related

ASP.NET MVC Cannot Implicitly Convert Type System.Collections.Generic.List<string> to 'string'

I'm trying to use EF to retrieve data from SQL and put it into a list of type viewmodel.
But when I try and retrieve the data it gives the following error: Cannot Implicitly Convert Type System.Collections.Generic.List<.string> to 'string'
I'm only trying to retrieve the ID and ProductName columns from the database.
Any help would be appreciated.
Here is my ViewModel:
public class ProductViewModel
{
public int ID { get; set; }
public string Product { get; set; }
}
Here is my controller code:
public ActionResult TableReport()
{
List<ProductViewModel> products = new List<ProductViewModel>();
ProductViewModel product = new ProductViewModel();
product.Product = db.Products.Select(z => z.ProductName).ToList();
product.ID = db.Products.Select(z => z.ProductID).ToList();
return View();
}
#GSerg: Read your code out loud. "Create an empty list of ProductViewModels. Create an empty ProductViewModel. Assign the list of all product names as the product name for that single empty ProductViewModel. Assign the list of all product ids as the id for that single empty ProductViewModel". No wonder it is not working, is it? Instead you should have done var products = db.Products.Select(z => new ProductViewModel() { ID = z.ProductID, Product = z.ProductName}).ToList();
You are putting a list in a string
Change your Viewmodel to
public class ProductViewModel
{
public int ID { get; set; }
public List<string> Product { get; set; }
}
And you are also trying to put a list in an int. That won't work either.

Sorting on nested Id property

Let's say we have a document like this
public class Event
{
public string Id { get; set; }
public EntityDescriptor Venue { get; set; }
// Other properties omitted for simplicity
}
public class EntityDescriptor
{
public string Id { get; set; }
public string Name { get; set; }
}
And an index like this
public class Events : AbstractIndexCreationTask<Event>
{
public Events()
{
Map = items => from e in items
select new
{
Venue_Id = e.Venue.Id,
Venue_Name = e.Venue.Name
};
}
}
When trying to sort on Event.Venue.Id
session.Query<Event, Events>().Take(10).OrderBy(e => e.Venue.Id).ToArray();
the sent request is
/indexes/Events?&pageSize=10&sort=__document_id&SortHint-__document_id=String
Is this by design or a bug?
PS: OrderBy(e => e.Venue.Name) works as expected (sort=Venue_Name).
It's not a bug. __document_id is the special known field containing the ID of the document. It's there regardless of whether you have an .Id property.
edit
I misread your question. This indeed appears to be a bug. I recommend you send a simple repro case to the Raven forum and let them know which RavenDB version you're using.

ASP.NET MVC cannot get dropdownlist to set selected value

In my ASP.NET MVC application, I have a drop-down list in a form on a page, where the dropdown list item that should be selected when the page loads don't get selected.
The ViewModel for the page has a property for the list of SelectListItems that should be used to populate the drop-down list:
See below for the View model and illustration of the "Index" class, which has HeaderItemID as one of it's properties:
public class IndexItemResult
{
public Index FocalIndex { get; set; }
public string FocalIndexHeaderItemText { get; set; }
public List<Item> IndexItems { get; set; }
public List<SelectListItem> ItemSelectList { get; set; }
public List<Item> ItemList { get; set; }
public IndexItemResult() { }
}
public class Index
{
public int IndexID { get; set; }
public string IndexName { get; set; }
public int IndexHeaderItemID { get; set; }
}
I set the "text", "value", and "selected" properties of items in the SelectListItems from a database LINQ query in my controller. This method also sets the "FocalIndex" property of the ViewModel. As HeaderItemID is a property of FocalIndex, I therefore assumed that "HeaderItemID" is available as a field that can be bound to.
"HeaderItemID" is the item that should be selected. When I look at the list of SelectListItems that gets generated, everything looks ok - the "text" and "value" properties are all fine, and the correct item is specified as "selected".
private IndexItemResult GetIndexItemResult(int? indexID)
{
IndexItemResult indexItemResult = new IndexItemResult();
Index focalIndex = db.Indexes.Find(indexID);
indexItemResult.FocalIndex = focalIndex;
int HeaderItemID = focalIndex.IndexHeaderItemID;
indexItemResult.ItemSelectList = db.ItemTexts.
Where(it => it.LanguageID == 1).
Select(iText =>
new SelectListItem
{
Selected =
(
iText.ItemID == HeaderItemID ? true : false
),
Value = iText.ItemID.ToString(),
Text = String.Concat(iText.ID.ToString(), " ", iText.Text)
}).ToList();
return indexItemResult;
}
I then have a form on the page, where I specify the dropdown list with the #Html.DropDownList helper. I pass the list of SelectListItems from the ViewModel in the second parameter.
#Html.DropDownList("IndexHeaderItemID", Model.ItemSelectList,
htmlAttributes: new { #class = "form-control", #id = "HeaderItemDDL" })
The drop-down list renders with all the items as expected, but the item that should be set at "selected" is not selected. Instead, the first item is selected. Any suggestions for what I'm missing here?
I see no place where you're actually setting anything in ModelState named IndexHeaderItemID. Since that is the name you're binding to, then one of Request["IndexHeaderItemID"], ViewData["IndexHeaderItemID"], ViewBag.IndexHeaderItemID or Model.IndexHeaderItemID must be set to the value you expect to be selected.

How do I implement Denormalized References in RavenDB

I would like to have a reference between two entities stored in the RavenDB document database. Since this is not a relational db I know that I am supposed to use the Denormalized Reference technique described on RavenDBs documentation. Whilst at first this seems fine, once I start to create a real-world domain ‘hierarchy’ including bidirectional references the effort of keeping all those references up to date feels disproportionate. I feel I may be going wrong somewhere.
Can you explain the best / simplest way to model a reasonably complex domain hierarchy using RavenDB?
Thanks
I am not sure whether this will go far enough to answer your question but here is how I go about creating a Denormalized Reference in RavenDB (this is taken from real code with non-essentials removed for clarity)
Domain
public class User : IUserIdentity
{
public string UserName { get; set; }
public IEnumerable<string> Claims { get; set; }
public string Id { get; set; }
public Guid FormsAuthenticationGuid { get; set; }
}
public class Assessment
{
public string Id { get; set; }
public UserReference User { get; set; }
public AssessmentState State { get; set; }
}
You can see that I have a Assessment class that references a User. This user reference are managed using the UserReference class below.
Denormalized Reference
public class UserReference
{
public string Id { get; set; }
public string UserName { get; set; }
public static implicit operator UserReference(User user)
{
return new UserReference
{
Id = user.Id,
UserName = user.UserName
};
}
}
Note how the reference class also carries the UserName. This value will not change very often but it may change so we need a way to update the UserName property in the UserReference property held in the Assessment class. To make the change we must first find the correct Assessment instances from RavenDB and for that we need an index.
Raven Index
public class Assessment_ByUserId : AbstractIndexCreationTask<Assessment>
{
public Assessment_ByUserId()
{
Map = assessments => from assessment in assessments
select new
{
User_Id = assessment.User.Id
};
}
}
This index needs to be invoked whenever a User's UserName value is updated. I have a UserService class that helps me co-ordinate all my User related functions, so that is where I put this code.
I reuse this code for other references so it has been abstracted out a little. This may help you create the more complex hierarchies (or perhaps 'domain graph' is a better description) you want.
UserService
public static void SetUserName(IDocumentSession db, string userId, string userName)
{
var user = db.Load<User>(userId);
user.UserName = userName;
db.Save(user);
UpdateDenormalizedReferences(db, user, userName);
}
private static void UpdateDenormalizedReferences(IDocumentSession db, User user, string userName)
{
db.Advanced.DatabaseCommands.UpdateByIndex(
RavenIndexes.IndexAssessmentByUserId,
GetQuery(user.Id),
GetUserNamePatch(userName),
allowStale: true);
}
private static IndexQuery GetQuery(string propertyValue, string propertyName = "User_Id")
{
return new IndexQuery {Query = string.Format("{0}:{1}", propertyName, propertyValue)};
}
private static PatchRequest[] GetUserNamePatch(string referenceValue, string referenceName = "User")
{
return new[]
{
new PatchRequest
{
Type = PatchCommandType.Modify,
Name = referenceName,
Nested = new[]
{
new PatchRequest
{
Type = PatchCommandType.Set,
Name = "UserName",
Value = referenceValue
}
}
}
};
}
That is it. And you know, now that I lay it all out I can see what you mean. It is a lot of work just to update a reference. Perhaps the Service code can be made more DRY and reused for different relationship types, but I don't see how to get away from writing lots of indexes, one per referenced type.

How can I sort in (n)hibernate on a property of a child object?

I have an object from my domain model that has a child object. How can I use a criteria query to order based on a property of the child?
For example:
class FooType
{
public int Id { get; set; }
public string Name { get; set; }
public BarType Bar { get; set; }
}
class BarType
{
public int Id { get; set; }
public string Color { get; set; }
}
...
// WORKS GREAT
var orderedByName = _session.CreateCriteria<FooType>().AddOrder(Order.Asc("Name")).List();
// THROWS "could not resolve property: Bar.Color of: FooType"
var orderedByColor = _session.CreateCriteria<FooType>().AddOrder(Order.Asc("Bar.Color")).List();
What do I need to do to enable this scenario? I'm using NHibernate 2.1. Thanks!
You need to either add an alias or create a nested criteria for your child. Not sure how to do this in NHibernate, in Hibernate it's done via createCriteria() and createAlias() methods.
You would then use the alias as prefix in order by.
Update Hibernate code sample:
Criteria criteria = session.createCriteria(FooType.class);
criteria.createAlias("bar", "b");
criteria.addOrder(Order.asc("b.color"));
I imagine in NHibernate it would be quite similar, though with property/entity names uppercased. Here's an example from NHibernate documentation.