I am trying to execute a sql command directly against the database. However, intellisense does not see ExecuteQuery as a valid method against my context variable. I am sure I am missing something obvious.
My context class:
public class CatastropheContext : DbContext
{
public DbSet<CLIENT> CLIENTs { get; set; }
...
}
My attempt to establish the query:
CatastropheContext db = new CatastropheContext();
IEnumerable<ClientClaim> = db.ExecuteQuery
In the code above, ExecuteQuery is flagged as invalid an intellisense suggests creating a stub method.
Can you use Database.ExecuteSqlCommand where Database comes from the DbContext class.
This seems to me like you are missing some references. Make sure you are:
using System.Data.Linq;
Here is the MSDN reference on ExecuteQuery. Notice the namespace.
Related
I originally developed a database(with UI) to add new records, retrieve list based on a query, and allow data alterations.
The two tables I used have now been incorporated into a SQL Server database, and I need to duplicate the same user experience in the new environment. I hope I am almost successful, but I still have errors in 2 files.
Within the ApplicationDbContext.cs file,
(1) I attempted to use the class name in declaring the DbSet statements. I get the following error in each instance:
"The type or namespace name '(className)' could not be found (are you missing a using directive or an assembly reference?)
(Should I be using something besides the class name in the DbSet statement?)
(2) I declare ApplicationDbContext as follows:
`public ApplicationDbContext() : base(ApplicationDbContext)
{}
The following error appears:
"'ApplicationDbContext' is a type, which is not valid in the given context"
In Startup.cs, ConfigureServices looks like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<ApplicationDbContext>(options =>
{
UseSqlServer(Configuration.GetConnectionString("AFForm1067DbConnection" ));
});
services.AddRazorPages();
//services.AddSingleton<IAFForm1067Repository,
MockAFForm1067Repository>();
}
I get the following error:
"The name 'UseSqlServer' does not exist in the current context"
Any help would be very much appreciated!
In my edmx model are 2 related tables: Challenge and ChallengeNote (has FK back to ChallengeID)
I can do this in breeze all day long
var qry = dataservice.getQuery("Challenges");
However, this fails every time:
var qry = dataservice.getQuery("Challenges").expand("ChallengeNotes");
The searchFailed is called and is the only error information in the console.
return dataservice.execute(qry.inlineCount(true))
.then(seachSucceeded)
.fail(searchFailed);
Does Breeze support relational data like this?
Does one need to write some custom code to support?
What am I missing?
Here's related answered question, but I was already following (unless I missed something) the answer's solution (and why I have the 2 context.Configuration settings in my ContextProvider).
breezejs-error-when-loading-an-entity-with-related-data
Here's another similar question that's been unanswered breeze-expand-query-fails-with-object-object-has-no-method-getproperty
Here's my provider code (want to use the BeforeSaveEntity override further on in the project):
public class ModelProvider : EFContextProvider<ModelEntities>
{
public ModelProvider()
: base()
{
this.Context.Configuration.LazyLoadingEnabled = false;
this.Context.Configuration.ProxyCreationEnabled = false;
}
}
Here's my controller code:
[BreezeController]
public class DataController : ApiController
{
readonly ModelProvider _contextProvider = new ModelProvider();
[HttpGet]
public string Metadata()
{
return _contextProvider.Metadata();
}
[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
[HttpGet]
public IQueryable<Challenge> Challenges()
{
return _contextProvider.Context.Challenges.Include(x => x.ChallengeNotes);
}
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
[HttpGet]
public IQueryable<ChallengeNote> ChallengeNotes()
{
return _contextProvider.Context.ChallengeNotes;
}
}
When I browse to the URL, it's including the related entity:
http://localhost:53644/breeze/data/Challenges?$filter=Active%20eq%20true&$top=10&$expand=ChallengeNotes&$inlinecount=allpages
Here is the data coming from the Controller
At this point all things, imo, are pointing to Breeze configuration on either the Server or Client.
TIA
Breeze absolutely does support this, but you do need to make sure that your Entity Framework model is set up correctly. Take a look at the DocCode sample in the Breeze zip for a number of examples of using both expand (client side) or EF include (server side) clauses.
One guess about your problem is that you are using the Breeze camelCasing naming convention and therefore your "expand" clause should be
var qry = dataservice.getQuery("Challenges").expand("challengeNotes");
i.e. "challengeNotes" (note the casing) is the name of the client side property that corresponds to a server side property of "ChallengeNotes". To clarify, "expand" clauses take the names of client side "properties" as parameters and property names are what are transformed as a result of the Breeze.NamingConvention.
In contrast, a query resource name i.e. "Challenges" in your example is the name of the server side resource ( as a result of marking your "Challenges" method with the [HttpGet] annotation. This name is NOT affected by the NamingConvention.
Side notes: Your example has both an expand and an Include clause. Either of these is sufficient all by itself. You do not need both. In general you can either include an "expand" clause in your client side query OR have an Entity Framework "Include" clause on the server. The advantage of the first is that you can control the expand on the client, the advantage of the second is that you can insure that every query for a specified resource always fetches some related entities.
Hope this helps!
I am using Entity Framework's code-first approach to create tables, and I need to check if there are any entities in the database that I need to delete:
class MyDocument
{
public string Id { get; set; }
public string Text { get; set; }
}
class MyContext : DbContext
{
public DbSet<MyDocument> Documents { get; set; }
}
using (var data = new MyContext())
{
var present = from d in data.Documents
where d.Id == "some id" || d.Id == "other id"
select d;
// delete above documents
}
on first run, when there is no table yet, the LINQ expression above throws an exception:
Invalid object name 'dbo.Documents'
How do I check if the table is there and if it is not, then set present to the empty set, perhaps? Or maybe there is a way to force database/table creation before I issue the LINQ query?
EF will actually check the entire context against the DB it is attached to.
The DB can have more than the context. But not less.
So actually you check
Context.Database.CreateIfNotExists();
If the DB and context dont match and you are using automatic migrations, then you get specific object errors. But this can be misleading in terms of the how EF is handling the context to DB comparison.
You could of course try and access every DBSet in a context
Not sure how useful that is though.
EF Code first supports Migrations, either Automated or on demand.
See EF Code first migrations
Database.SetInitializer
use SetInitializer command to turn on automatic migrations for example.
The link will provide more info on the Manual/controlled approach to db migration for advanced db handling. The easier Automatic approach, is also described in the link.
Right now, I have a domain entity named StyleBundle. This StyleBundle takes a list of Styles:
public class StyleBundle
{
public StyleBundle(List<Style> styles)
{
this.Styles = styles;
}
public IEnumerable<Style> Styles { get; private set;}
}
So, in my original design, a StyleBundle should never be created with an empty Style list. This was a rule that the domain experts basically said was good.
I wrote this using a guard clause in the constructor:
if (styles.Count() == 0)
throw new Exception("You must have at least one Style in a StyleBundle.");
which made sure I could not create StyleBundle in an invalid state. I thought an exception made sense here b/c a StyleBundle being created without at least one Style was exceptional in the system.
Of course, change came down the road during the rest of the project, and now it should be possible for a user to create a StyleBundle without Styles, but they should not be allowed to PERSIST a StyleBundle without Styles.
So now I'm looking at my guard clause and realizing that I can't have the exception thrown from the constructor anymore.
Moving forward, I have a Service/Application layer that my code-behinds interact with when they're working with StyleBundles. In my Service Layer, I have a StyleBundleService class, and that class exposes basic functionality to the UI... among them is "CreateStyleBundle".
It seems as if I'll have to have my Service Layer check to see if the StyleBundle does or does not have any Styles before it's persisted to the database, but something about this decision feels "wrong" to me.
Anyone run into a similar thing? Basically, the different between the state of an object being valid when "new'ed up" vs. the state of the same object when it comes to persistence?
Thanks!
Mike
I would add an IsValid method to your entity. This would check if the entity is currently in a valid state (in your case, check if there are styles).
This method can be called from your Repository to check if an entity may be persisted. You can add more rules to the IsValid method for specific entities and you can implement something like a collection of Validation errors is you want to throw a meaningful exception.
Expanding what Wouter said, plus handy BeforeSaving and BeforeDeleting methods:
public interface IDomainObject<T>
{
bool IsValid();
}
public interface IEntity<T> : IDomainObject<T>
{
}
public interface IAggregateRoot<T> : IEntity<T>
{
void BeforeSaving();
void BeforeDeleting();
}
public interface IAggregateRoot { //or simply IEntity depending on the model
bool IsValid();
}
public class StyleBundle : IAggregateRoot<T> {
return styles.Count() > 0
}
public class StyleBundleRepository : Repository<StyleBundle> {
}
public abstract class Repository<T> : IRepository<T> where T : class, IAggregateRoot<T> {
public T Save(T t)
{
t.BeforeSaving(); //for all AggregateRoots, maybe logging what the aggregate was like before the changes
if(!t.IsValid())
throw Exeception("Entity invalid");
EntityStore.Current.SaveChanges();
// "AfterSaving" here, i.e.: log how the entity looks after the update
}
}
Edit: I dont personally use the IsValid idea, I go with a full class of EntityValidationErrors where I can report back to the client what was wrong before attempting to save, things that shouldnt be null, shouldnt be empty (like your Styles etc)
There are multiple strategies:
Some developers prefer to create 2 methods in the entity itself, one called IsValid() which validates the entity in terms of business rules (general validation) and another one called IsValidForPersistence() which validates the entity for persistence.
Regarding IsValid() I prefer instead not to allow invalid state in the first place by validating all inputs, and to support invariants I use factory or builder.
you may check the link http://www.codethinked.com/thoughts-on-domain-validation-part-1
for some thoughts.
I know, this question is three years old, but seeing the current answer is something I like to respond to. We are talking about the domain data. Hence, there can't be a valid StyleBundle with 0 objects. I imagine, you have a frontend editor somewhere, were you create a "new" StyleBundle and have to add at least one style, before hitting the "save" button.
At this point in the frontend, you won't have a domain object. You may have a data transfer object, that will be send with a "CreateNewStyleBundle" command.
In my opinion, the domain object must be agnostic to persitance and should always be in a valid state. If you have to call a "IsValid" method, you circumvent the whole idea of having domain objects in the first place.
That's just my humble opinion.
I'm using logical delete in my system and would like to have every call made to the database filtered automatically.
Let say that I'm loading data from the database in the following way :
product.Regions
How could I filter every request made since Regions is an EntitySet<Region> and not a custom method thus not allowing me to add isDeleted = 0
So far I found AssociateWith but I'd hate to have to write a line of code for each Table -> Association of the current project...
I'm looking into either building generic lambda Expressions or.. something else?
You could create an extension method that implements your filter and use that as your convention.
public static class RegionQuery
{
public static IQueryable<Region> GetAll(this IQueryable<Region> query, bool excludeDeleted=true)
{
if (excludeDeleted)
return query.Regions.Where(r => !r.isDeleted);
return query.Regions;
}
}
So whenever you want to query for regions you can make the following call to get only the live regions still providing an opportunity to get at the deleted ones as well.
context.Regions.GetAll();
It my be a little wonky for access the Products property, but still doable. Only issue is you would have to conform to the convention. Or extend the containing class.
someProduct.Regions.GetAll();
I hope that helps. That is what I ended up settling on because I haven't been able to find a solution to this either outside of creating more indirection. Let me know if you or anyone else comes up with a solution to this one. I'm very interested.
It looks to me like you're using a relationship between your Product and Region classes. If so, then somewhere, (the .dbml file for auto-generated LINQ-to-SQL), there exists a mapping that defines the relationship:
[Table(Name = "Product")]
public partial class Product
{
...
private EntitySet<Region> _Regions;
[Association(Storage = "_Regions")]
public EntitySet<Region> Regions
{
get { return this._Regions; }
set { this._Regions.Assign(value); }
}
...
}
You could put some logic in the accessor here, for example:
public IEnumerable<Region> Regions
{
get { return this._Regions.Where(r => !r.isDeleted); }
set { this._Regions.Assign(value); }
}
This way every access through product.Regions will return your filtered Enumerable.