I am trying to create CQL query which will select assemblies created by my company.
In my opinion the easiest way is to check data generated in AssemblyInfo, but I cannot find how to access it in CQL.
What about the code query:
from a in Application.Assemblies
where a.Name.StartsWith("YourCompany.YourProduct")
select a
Or do you need something more sophisticated?
Ok, what about getting inspiration from this default rule:
// <Name>UI layer shouldn't use directly DB types</Name>
warnif count > 0
// UI layer is made of types in namespaces using a UI framework
let uiTypes = Application.Namespaces.UsingAny(Assemblies.WithNameIn("PresentationFramework", "System.Windows", "System.Windows.Forms", "System.Web")).ChildTypes()
// You can easily customize this line to define what are DB types.
let dbTypes = ThirdParty.Assemblies.WithNameIn("System.Data", "EntityFramework", "NHibernate").ChildTypes()
// Ideally even DataSet and associated, usage should be forbidden from UI layer:
// http://stackoverflow.com/questions/1708690/is-list-better-than-dataset-for-ui-layer-in-asp-net
.Except(ThirdParty.Types.WithNameIn("DataSet", "DataTable", "DataRow"))
from uiType in uiTypes.UsingAny(dbTypes)
let dbTypesUsed = dbTypes.Intersect(uiType.TypesUsed)
select new { uiType, dbTypesUsed }
Of course the sets uiTypes and dbTypes must be refined with assemblies from level N and assemblies from level N+1.
Related
Setting:
One db with many tables, grouped by modules. The moduleTableGroups are independent, there are no relationships in between.
Design:
1: The modules have each there own Context, to keep them small and clear.
2: Because it is an very old Database with manual administration of PKeys and sequences it must be possible to nest SaveChanges, when handling those things in the context.
E.G. AContext has a table with an entity which has a ValueGenerator which reads an incremented value from a table. Because it should be finished before AContext.SaveChanges(), is called, it must be done in an seperate SeqContext in the same db which can handle the concurency issues which might occur.
The SeqContext depends on the DbOptionsContext of AContext.
Wishes:
1: Instead of create Options for each Context which is currently needed, becaus a context seems only to accept context specific options, I'd like to either use the same DbContextOptions for many context or copy or cast the options to a new .
DbContextOptions<AContext> aContextOptions = new DbContextOptionsBuilder<AContext>(). . .Options;
// casting:
DbContextOptions<BContext> bContextOptions = (DbContextOptions<BContext>) aContextOptions;
// copy construction:
DbContextOptions<BContext> bContextOptions = new DbContextOptionsBuilder<BContext>(aContextOption).Options;
2: Because of the dependency of SeqContext to AContext especially in testing scenarios it would be useful to do something from within a AContext like:
SeqContext = new SeqContext((DbContextOptions<SeqContext>) this.getOptions());
You might get the idea. How can I archive to share options between different TContext right now?
How should I transform this query into a valid Entity Framework query?
dbSet.Include(x=>x.Offer.Images.Where(y=>y.IsDeleted == false))
The Where clause throws an exception:
The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.
I already tried third party library IncludeFilter, which works. However it doesn't allow me to use another include:
dbSet.Include(x=>x.Offer.Images.Where(y=>y.IsDeleted == false)).Include(x=>x.Demand)
Many thanks :-)
Include is just a marker to tell EF to eager-load related entities. It doesn't support eager-loading a selected sub-set of relatives, such as active items.
When working with a soft-delete model (IsDeleted/IsActive) will populate the view models with the active children. The benefit of returning view models for read operations is that you avoid potential lazy-load scenarios and just retrieve the data you need to consume. For edit operations I will eager-load related data and typically want both active and inactive records.
var viewModels = dbset.Select(x => new MyVM
{
Objectid = x.ObjectId,
// ...
Offer = new OfferViewModel
{
OfferId = x.Offer.OfferId,
// ...
Images = x.Offer.Images
.Where(i => !i.IsDeleted) // Load only active images
.Select(i => new ImageViewModel
{
ImageId = i.ImageId,
//...
}).ToList()
}
}
Note that this doesn't need explicit .Include() statements, just load the data that you need.
When I go to save changes to the entity graph then I would load the root entity with .Include(x => x.Order).Include(x => x.Order.Images) to ensure that I have all relative data included. EF should be aware of the full collection before applying updates to avoid surprises such as duplicate record insertion attempts.
I already tried third party library IncludeFilter, which works. However it doesn't allow me to use another include:
When starting to use IncludeFilter, you need to continue using it all the way even if you don't filter.
dbSet.IncludeFilter(x=>x.Offer.Images.Where(y=>y.IsDeleted == false))
.IncludeFilter(x=>x.Demand)
I created an extension with a domain model Message. This model has a relation m:n with the TYPO3 pages (the one which has the details of the pages, like title, issite_root etc) table. However, by using the mapping to existing tables option, it gives me type error saying page :
The configured type field for table "pages" is of type int(11) unsigned
This means the type field can not be used for defining the record type.
You have to configure the mappings yourself if you want to map to this
table or extend the correlated class
So I just create the relation without mapping, so that I can later map it from setup.txt.
The I created model Pages in MyExt/Classes/Domain/Model/ with all the getters/setters and repository in MyExt/Classes/Domain/Repository/.
In my setup.txt I did this:
config.tx_extbase {
persistence{
enableAutomaticCacheClearing = 1
updateReferenceIndex = 0
classes {
Tx_Playfield_Domain_Model_Pages {
mapping {
tableName = pages
columns {
uid.mapOnProperty = uid
pid.mapOnProperty = pid
sorting.mapOnProperty = sorting
title.mapOnProperty = title
subtitle.mapOnProperty = subtitle
}
}
}
}
}
}
But when I try to access the Pages model I created,
var_dump($this->pagesRepository->findByUid(74));
its searching for tx_playfield_domain_model_pages which does not exists, it shows
Table 'typo3.tx_playfield_domain_model_pages' doesn't exist: SELECT tx_playfield_domain_model_pages.* FROM tx_playfield_domain_model_pages WHERE tx_playfield_domain_model_pages.uid = '74' LIMIT 1
What am I missing here?
Update
After following http://t3-developer.com/extbase-fluid/cheats-extbase/model/tabelle-pages-in-extbase/ suggested by #Michael I get an empty result from $this->pagesRepository->findByUid(74)
setup.txt is loading. I did this to check it:
plugin.tx_playfield{
settings{
temp=yes
}
}
And this is being accessed from my controller.
Is it possible that you didn't create the Pages domain model (within the extension builder or not at all)? The file my_ext/Classes/Domain/Model/Pages.php needs to exist. Check that your "Pages" domain model has the property Map to existing table set to pages, it should look like that:
I don't know where exactly your error is, but I did some more tinkering in the extension builder and made it work. You can probably find out by comparing your extension playfield to my temporary extension testfield: Download it here (updated).
Btw, you don't need to map properties that you do not want to be displayed in the frontend unless they are named differently.
mapping {
tableName = pages
columns {
title.mapOnProperty = title
subtitle.mapOnProperty = subtitle
}
}
I think you have to write the mapping with camel case letters (the class name). Although this post is in German, I think the code might help you. The author added some fields he is going to use to the class and also added a mapping in the typoscript of the extension (see the example code there). The most important part of the German text is that this example there was designed only to read from the db. If you want to create new pages using the model, you have (at least) to add the TCA and setters in the model class to make it work.
My question is this: How can you implement a default server-side "filter" for a navigation property?
In our application we seldom actually delete anything from the database. Instead, we implement "soft deletes" where each table has a Deleted bit column. If this column is true the record has been "deleted". If it is false, it has not.
This allows us to easily "undelete" records accidentally deleted by the client.
Our current ASP.NET Web API returns only "undeleted" records by default, unless a deleted argument is sent as true from the client. The idea is that the consumer of the service doesn't have to worry about specifying that they only want undeleted items.
Implementing this same functionality in Breeze is quite simple, at least for base entities. For example, here would be the implementation of the classic Todo's example, adding a "Deleted" bit field:
// Note: Will show only undeleted items by default unless you explicitly pass deleted = true.
[HttpGet]
public IQueryable<BreezeSampleTodoItem> Todos(bool deleted = false) {
return _contextProvider.Context.Todos.Where(td => td.Deleted == deleted);
}
On the client, all we need to do is...
var query = breeze.EntityQuery.from("Todos");
...to get all undeleted Todos, or...
var query = breeze.EntityQuery.from("Todos").withParameters({deleted: true})
...to get all deleted Todos.
But let's say that a BreezeSampleTodoItem has a child collection for the tools that are needed to complete that Todo. We'll call this "Tools". Tools also implements soft deletes. When we perform a query that uses expand to get a Todo with its Tools, it will return all Tools - "deleted" or not.
But how can I filter out these records by default when Todo.Tools is expanded?
It has occurred to me to have separate Web API methods for each item that may need expanded, for example:
[HttpGet]
public IQueryable<Todo> TodoAndTools(bool deletedTodos = false, bool deletedTools = false)
{
return // ...Code to get filtered Todos with filtered Tools
}
I found some example code of how to do this in another SO post, but it requires hand-coding each property of Todo. The code from the above-mentioned post also returns a List, not an IQueryable. Furthermore this requires methods to be added for every possible expansion which isn't cool.
Essentially what I'm looking for is some way to define a piece of code that gets called whenever Todos is queried, and another for whenever Tools is queried - preferably being able to pass an argument that defines if it should return Deleted items. This could be anywhere on the server-side stack - be it in the Web API method, itself, or maybe part of Entity Framework (note that filtering Include extensions is not supported in EF.)
Breeze cannot do exactly what you are asking for right now, although we have discussed the idea of allowing the filtering of "expands", but we really need more feedback as to whether the community would find this useful. Please add this to the breeze User Voice and vote for it. We take these suggestions very seriously.
Moreover, as you point out, EF does not support this.
But... what you can do is use a projection instead of an expand to do something very similar:
public IQueryable<Object> TodoAndTools(bool deleted = false
,bool deletedTools = false) {
var baseQuery = _contextProvider.Context.Todos.Where(td => td.Deleted == deleted);
return baseQuery.Select(t => new {
Todo: t,
Tools: t.Tools.Where( tool => tool.Deleted = deletedTools);
});
}
Several things to note here:
1) We are returning an IQueryable of Object instead of IQueryable of ToDo
2) Breeze will inspect the returned payload and automatically create breeze entities for any 'entityTypes' returned (even within a projection). So the result of this query will be an array of javascript objects each with two properties; 'ToDo' and 'Tools' where Tools is an array of 'Tool' entities. The nice thing is that both ToDo and Tool entities returned within the projection will be 'full' breeze entities.
3) You can still pass client side filters based on the projected property names. i.e.
var query = EntityQuery.from("TodoAndTools")
.where("Todo.Description", "startsWith", "A")
.using(em);
4) EF does support this.
Can any one tell me how to use AddCommand rather than `SetCommand" to do the following.
I have a class like this:
class Profile {
List achievements;
List grades;
List extracurrics;
}
Now, suppose I need to add a grade object to this Profile object,how can I achieve this by using AddCommand only
SetCommand is basically used to set values in EMF model, and AddCommand is used to modify collection values inside EMF model, so in general it should not be a problem to use AddCommand.
You can create new AddCommand using static creation function in AddCommand:
AddCommand.create(EditingDomain domain, EObject owner, EStructuralFeature feature, java.lang.Object value)
Explanation of given values:
domain: the editing domain your model lives in
owner: element you are doing the modifications to
feature: feature in model, that should be given to you by the EPackage of your model.
So this case is the Grades list feature
value: the new object you add to the list
There are many different create helpers in add command, so if you need to define index to list, it is also doable.
I don't have EMF running here, so I cannot provide any direct sources, but let me know if that didn't do the trick.
It should look something like this:
Profile p = ...;
Grade g = ...;
Command add = AddCommand.create(domain,p, YourProfilePackage.Literals.PROFILE__GRADES, Collections.singleton(g));
where YourProfilePackage should be in the code generated automatically from your EMF model.