Say we have
using (var lobo = new MyGymEntities())
{
}
I would like to get the DbContext name (in this case is MyGymEntities) with reflection, is this possible?
I would like to store the string value into a variable..
Edit:
I do not want to type MyGymEntities.GetType().Name/FullName to do this.
I'm asking if it is possible to somehow obtain this information from the assembly such as
Assembly.GetExecutingAssembly().GetName().Name; //Return Projectname
UPDATE
The following solved my problem, in case anyone
var a = Assembly.GetExecutingAssembly()
.DefinedTypes
.Where(x => x.BaseType?.Name == "DbContext").ToList();
Console.WriteLine(a.First().FullName);
Ok, guys, I'll explain why this question is not a duplicate and why I want to get the name of the DbContext.
I'm well aware that the name property of an object can be accessed by calling the GetType().Name on it, but this method can only be called by an object itself meaning I need to specify which objects name attribute I would like to retrieve.
Ex:
MyObject.GetType().Name;
However what I want to do is: to get the DbContextName(if there's any) that is on the project, solution.
why do I need this? because I have generic Forms that handle my queries
inside my Custom Forms currently, I have something like this
MyGymEntities context = new MyGymEntities();
now If I copy and paste the current solution folder to create a new project I'll have to rename the DbContext shown above to the name of the new DbContext for my solution.
however, If I use this to get the ContextName, than I'll create a new instance of the DbContext of this name and use it on my Custom Forms, therefore will need less configuration for each project I'll be creating...
var ContextName = Assembly.GetExecutingAssembly()
.DefinedTypes
.Where(x => x.BaseType?.Name == "DbContext").ToList().First().Name;
Thanks!
BaseType only returns the immediate base type, and will break if you later introduce a custom base DbContext. You can get all the DbContext types in an assembly with something like:
var dbContextTypes = Assembly.GetExecutingAssembly()
.DefinedTypes.Where(t => typeof(DbContext).IsAssignableFrom(t))
.ToList();
Related
I'm currently working on an API and the library I'm using needs to initialize most of its components. It is initialize by using .include.
A sample call would be: context.Load(context.Projects, proj => proj.Include(p => p.Name))
As much as possible, I don't want to include a lot of fields since it will take longer to execute the query. So one of my idea was to use GetType().GetProperty(), which looks like this:
context.Load(context.Projects, proj => proj.Include(
p => p.Name,
p => p.GetType().GetProperty(customFieldName)
));
My assumption was that when I do this I will get the property, but it seems it creates a different object. Is there any way I can do this?
Edit: The idea is that the customFieldName is given by the user, so for example the user gave Id I'm hoping to get the equivalence too p.Id in the Include statement. So I can return the value of that object to user
Entity framework also allows you to include properties based on their name as a string. In this way you can decide the property to include at runtime. So your code should now look something like this.
context.Load(context.Projects, proj => proj.Include("Name", customFieldName));
In case you are looking into nested properties (for ex: Name is a class with properties FirstName and LastName), you could use dot to specify the exact property to include ("Name.FirstName").
I've read this page, but it didn't have the answer. https://github.com/MapsterMapper/Mapster/wiki/Ignoring-members
What I want is to ignore all Id fields when the Source type is named like SomethingDto or FooDto
Something like this...
TypeAdapterConfig<TSource, TDestination>
.NewConfig()
.IgnoreIf((src, dest) => src.GetType.Name.EndsWith("Dto"), dest => dest.Id);
Another question, how could I set a global type mapping, then in the middle of a method, start using this new one and when the method ends, it reverts back to the original global setting? I might not want to always ignore Ids, for example.
I have something for the second half of my question. Make a clone of your global config, ignore all columns named Id or whatever, then inject that config into your Adapt<> method. Once the method exists, you revert back to global config settings.
var mapsterConfig = TypeAdapterConfig.GlobalSettings.Clone();
mapsterConfig.Default.Ignore("Id");
var entity = dto.Adapt<Entity>(mapsterConfig);
I'm trying to programmatically create indexes corresponding to several types, so I can search through items of specific types in my controllers. (I tried using the type keyword in Lucene, but that seems to not work at all no matter what I do, so I changed my approach.)
However, I can't figure out how to tell Orchard to include a specific type in an index in a migration. I tried using:
var typeIndexing = ContentDefinitionManager.GetTypeDefinition(contentType)
.Settings.GetModel<TypeIndexing>();
typeIndexing.List = typeIndexing.List.Concat(indexName.Yield()).ToArray();
but that just returns null as the result of GetTypeDefinition().
I'm looking at using:
ContentDefinitionManager.AlterTypeDefinition(contentType, builder => {
builder.WithSetting("TypeIndexing.Indexes", indexName);
});
but that seems like it replaces the previous configured index, if it works at all (EDIT: nope), and I don't want to clobber the existing setting. (A different person on the team is handling our setup recipe.)
Is there any place where I could touch that setting and have it be stored and actually used by Orchard outside the recipe file?
To illustrate what I'm trying to accomplish using the analogous admin UI changes, under Content Definition > [Content Type Name] > Edit:
Before:
After:
What you're looking for is the Indexed() extension method. It accepts the indexes you want to use on the content type.
ContentDefinitionManager.AlterTypeDefinition(nameof(contentType),type =>
type
.Indexed("FirstIndex", "SecondIndex"));
I am trying to use Autofac specifying 2 metadata items. It seems to add these fine, however, I am not too clear on how to retrieve the service by specifying both of these items. I have metadata items for an Assembly Name and a Version. The registration snippet is as follows:
builder.RegisterAssemblyTypes(assembly).Where(
t => t.GetInterfaces().Any(i =>
plugin.Interface == i.Name)).As<IPlugin>()
.WithMetadata<IMetaDataName>(m => m.For(pn => pn.Name, name)
.WithMetadata<IMetaDataVersion>(m => m.For(pn => pn.Version, version)
The only documentation and examples I can find specify that I can use this syntax:
IEnumerable<Lazy<IPlugin, IMetaDataName>>
in the costructor of the class or in a class that resolves the service I am after. What I am after is a mechanism to let me do the following:
Get the service that has the MetaDataName == "Service1" AND MetaDataVersion == "1.4"
Currently I have concatenated the two together for 1 metadata type which works but feels clunky. Is there are better approach to this?
Thanks
Craig.
Rather than concatenate both interfaces into one, you can just create a separate concatenated interface for the importer.
The interface name used at registration time doesn't have to match the one used as a dependency - the property names are the only shared information at this point.
The metadata view type used in a dependency is really specific to the class receiving the dependency rather than the type providing it, so these can vary independently.
Know this isn't exactly the answer you were looking for but hope it helps.
It is well know that if we have an EntityObject that there is no way to find the ObjectContext that it belongs to. That's fair enough I guess, but why is it that we can lazy load objects then? Surely the process of lazy loading has to get access to the ObjectContext in order to load the new objects?
The accepted answer is limited in that it can only work if the entity has at least one relationship.
However, this can also be done via reflection:
public ObjectContext Context(EntityObject entity) {
var relationshipManager = ((IEntityWithRelationships)entity).RelationshipManager;
var wrappedOwnerProperty = relationshipManager.GetType().GetProperty("WrappedOwner",BindingFlags.Instance | BindingFlags.NonPublic);
var wrappedOwner = wrappedOwnerProperty.GetValue(relationshipManager);
var contextProperty = wrappedOwner.GetType().GetProperty("Context");
return (ObjectContext)contextProperty.GetValue(wrappedOwner);
}
In VB.NET:
Function Context(entity As EntityObject) As ObjectContext
Dim relationshipManager = DirectCast(entity, IEntityWithRelationships).RelationshipManager
Dim wrappedOwnerProperty = relationshipManager.GetType.GetProperty("WrappedOwner", BindingFlags.Instance Or BindingFlags.NonPublic)
Return wrappedOwnerProperty.GetValue(relationshipManager).Context
End Function
NB: This was tested under .NET Framework v. 4.5.1. YMMV, as this depends on the internal WrappedOwner property and the Context property on the internal BaseEntityWrapper<TEntity> class. Nevertheless, if earlier/leter versions of .NET have different internal properties/classes it should be simple enough to do something similar.
NB: This could further be improved by making it an extension method on EntityObject, and by taking a generic parameter to return a strongly typed ObjectContext. It could also be simplified by using some sort of method to get property values by name.
You are right, given an object, we don't know what context it belongs to, or what session it is attached to. But Lazy Loading happens like this :
var firstPost = _Context.Posts.First()
var commentList = firstPost.Comments
When you say _Context.Posts.First() then one post is loaded.
Then when you say firstPost.Comments that's when the comments list is loaded.
This is possible because the type of your Comments field in your Post is probably an IList or some such generic interface : this is because EF4 can put a proxy list instead of the actual comment list. The proxy list knows about the _Context - knows about which session or context it is attached to. Hence it is able to load an actual list on demand.