how to query class inheritance in c#? - asp.net-mvc

is there any way to query how many class inherit a class using linq and reflection ?
eg. how to know classes that inherit from System.Web.Mvc.ActionResult in System.Web.Mvc.dll

if you want to retrieve only classes, and not interfaces (IsAssignablefrom returns also interfaces), you should try
var t = typeof(System.Web.Mvc.ActionResult);
var asmb = Assembly.GetAssembly(t);//or get all assemblies you need and put next code in loop
return asmb.GetTypes().Where(x=>x.IsSubClassOf(t)).ToList();

You can do this with two methods, 1. IsAssignableFrom, 2. assembly.GetTypes:
var t = typeof(System.Web.Mvc.ActionResult);
var asmb = Assembly.GetAssembly(t);
return asmb.GetTypes().Where(x=>x.IsAssignableFrom(t) && x != t);

Related

Count items in ViewResult or ActionResult - MVC Visual Studio

I need to unit test the controllers method results with the following code
StoreController test = new MvcMusicStore.Controllers.StoreController();
ActionResult result = test.Index();
ViewResult p = (ViewResult)result;
result and p shows 10 items in the model when debugging but it seems that I can not do Count or foreach to check how many records are returned as both objects are dictionary.
How can this be done?
Thanks
ViewResult.Model is of type object you have to cast it to the collection type first to get a count.
For example, if you're passing the list of integers as a model to your view, you can get the count this way:
var model = p.Model;
var list = model as List<int>();
var count = list.Count;
Assuming you have a model of IEnumerable<DataType> and you want to get this model in a unit test, you have to cast the result.ViewData.Model to your type and then do your Assertions:
var test = new StoreController();
var result = test.Index() as ViewResult;
var data = (IEnumerable<ModelType>) result.ViewData.Model;
Assert.AreEqual(10, data.Count());
Reference: https://www.asp.net/mvc/overview/older-versions-1/unit-testing/creating-unit-tests-for-asp-net-mvc-applications-cs (Listing 4)

F# : A Class as an argument (Lucene.net 3.0.3)

Let's say i have an instruction :
CharTermAttribute cattr = stream.addAttribute(CharTermAttribute.class);
Note : CharTermAttribute.class is a class
In F#, it's could be like this :
let cattr:CharTermAttribute = stream.addAttribute(..........)
How can i say to F# that (CharTermAttribute.class ) is a class
I'm not a Lucene.NET expert, but if you are trying to call this AddAttribute method then in the .NET version, this is a generic method and you can call it as:
let cattr = stream.addAttribute<CharTermAttribute>()
According to Ali Yacine question and the error: AddAttribute() only accepts an interface that extends Attribute, you must use interface of the types CharTermAttribute, etc in generic constraints of AddAttribute<> method. for example below:
var cattr = stream.AddAttribute<ICharTermAttribute>();
var another= stream.AddAttribute<IPositionIncrementAttribute>();

return LINQ Query result in IList and read it another class [duplicate]

This question already has answers here:
Working with C# Anonymous Types
(8 answers)
Closed 8 years ago.
I am using ASP.NET mvc 5. I have one class that holds all the LINQ which can access to another class. now i convert the LINQ query to list variable Query and returning as IList... the i create object of this class--> call the method and get result.
now i can see in debugging object names but i can't see in foreach loop. my list hold mix data types, plus result is merging from different tables...
public IList GetAllFeeZonesForFeeSchemeByID(int FeeSchemeID)
{
using (var db = new QualificationContext())
{
var Query = from a in db.FeeScheme
join b in db.FeeZoneSchema.Where(c => c.FeeSchemeID == 1) on a.FeeSchemeID equals b.FeeSchemeID
join c in db.FeeZone on b.FeeZoneID equals c.FeeZoneID
select new
{
FeeScheme = a.FeeSchemeID,
FeeZone = b.FeeZoneID,
FeeZone_Description = c.FeeZoneDescription
};
return Query.ToList();
}
}
in controller class...
foreach(var item in obj1.GetAllFeeZonesForFeeSchemeByID(1))
{
item.???? (can't access the object here....
}
many thanks
You should return Generic IList of concrete (not anonymous class):
public IList<FeeSchemeModel> GetAllFeeZonesForFeeSchemeByID(int FeeSchemeID)
{
using (var db = new QualificationContext())
{
var Query = from a in db.FeeScheme
join b in db.FeeZoneSchema.Where(c => c.FeeSchemeID == 1) on a.FeeSchemeID equals b.FeeSchemeID
join c in db.FeeZone on b.FeeZoneID equals c.FeeZoneID
select new FeeSchemeModel
{
FeeScheme = a.FeeSchemeID,
FeeZone = b.FeeZoneID,
FeeZone_Description = c.FeeZoneDescription
};
return Query.ToList();
}
}
public class FeeSchemeModel
{
public int FeeScheme{get;set;}
public int FeeZone{get;set;}
public string FeeZone_Description{get;set;}
};
But I recommend to use IEnumerable<T> instead of IList<T> and use ToArray() method instead of ToList() method if you don't use special features of List<T> (such as method Add())
IList is non-generic interface, it contains only non-generic IEnumerable definition, which enumerates objects. So type of item will be object. That's why you can see only members of System.Object class.
You should either cast item to appropriate type or use generic collection parametrized with appropriate type. But you can't use neither of these approaches while you are using anonymous objects, because you don't know anonymous type name. So, you need to create some class which you will be able to cast to:
foreach(Foo item in obj1.GetAllFeeZonesForFeeSchemeByID(1))
Or use as parameter of method return type:
public IList<Foo> GetAllFeeZonesForFeeSchemeByID(int FeeSchemeID)
One more option is usage of dynamic type, which will resolve operations on object at runtime. You still will not be able to use IntelliSense but your code will work:
foreach(dynamic item in obj1.GetAllFeeZonesForFeeSchemeByID(1))
{
// use item.FeeScheme
}

Entity Framework - Programmatically add Includes to ObjectQuery

I have a Entity Framework model where I have a user which has the following relationships:
User 1-* Test
Each Test has the following relationships:
Test 1-1 Course
Test 1-* TestEvent
I have a service that returns a user and at different points in my application I want to eagerly fetch various relationships. I am fetching all the relationships at present:
var result = (from appUser in context.AppUsers.Include("Tests.Course")
.Include("Tests.TestEvents")
where appUser.Login.ToLower() == loginName.ToLower() &&
appUser.IsDeleted == false
select appUser).FirstOrDefault();
I do not want to always return the Course linked to a Test or the TestEvents. How can I build an ObjectQuery and dynamically add the Include statements as required rather than having a series of if else statements.
Well, since Include returns an IQueryable<T> (LINQ chainable), i would use a simple extension method:
public static IQueryable<T> WithIncludes<T>(this IQueryable<T> source, string[] associations)
{
var query = (ObjectQuery<T>)source;
foreach (var assoc in associations)
{
query = query.Include(assoc);
}
}
Then your query looks like this:
var inclusions = new[] { "Tests.Course", "Tests.TestEvents" };
var result = ctx.AppUsers
.WithIncludes(inclusions)
.Where(x => x.Login.ToLower() == loginName.ToLower())
.Where(x => !x.IsDeleted)
.FirstOrDefault();
To get some strong-typing into the otherwise magic-string nature of include, i have specialized enums for all associations, so i pass an [] of those through and convert the enum to the string include.
The thing is, your methods should define what inclusions are required. So first thing you do in the method is declare what associations are required, then pass that to your extension method.
Is that what your after?

LINQ - Join Two Entities into One IQueryable Complex Type - EF4 and ASP.Net MVC

I have code like:
var entityX = this._xService.GetAll();
var entityY = this._yService.GetAll();
Both are returned as IEnumerable types. I need to inner join the two into a something like a JoinedList class that has to be IQueryable.
I'm looking for ways to do this please using LINQ.
Many Thanks
LINQ to Objects is excellent glue:
var entityX = this._xService.GetAll();
var entityY = this._yService.GetAll();
var joinedSequence = from x in entityX
join y in entityY on x.Key equals y.Key
select new { x, y };
var joinedQueryable = joinedSequence.AsQueryable();
You shouldn't really need that last step; IQueryable<T> is unnecessary because LINQ to Objects works just fine with IEnumerable<T>.

Resources