I have an object
public partial class FileAttachment
{
public FileAttachment()
{
this.Tags = new HashSet<Tag>();
}
public virtual ICollection<Tag> Tags {get; set;}
...other propertties
}
My context class is having
public virtual DbSet<FileAttachment> FileAtttachments {get; set;}
public virtual DbSet<Tag> Tags {get; set;}
public virtual DbSet<Item> Items {get; set;}
...
I am using it in my controller like
MyContext.Items.AsNoTracking().Where(i => i.ItemId == inputId &&
MyContext.FileAttachments.AsNoTracking.Where(f => f.RecordId == i.ReferenceId && f.RecordType == 'item').Any()).Any();
The error I am getting is
'Method 'System.Data.Entity.Infrastructure.DbQuery1[Demo.FileAttachment] AsNoTracking()' declared on type 'System.Data.Entity.Infrastructure.DbQuery
1[Demo.FileAttachment]' cannot be called with instance of type 'System.Data.Entity.Core.Objects.ObjectQuery`1[Demo.FileAttachment]''
I am new to AsNoTracking(). Anyone can tell where I am doing wrong?
CodePudding user response:
It looks like the actual requirement is to check whether an Item
with a specific ID has a related FileAttachment of a specific type. There's no need for AsNoTracking()
for this since the query returns a single boolean, not objects that need tracking.
If the classes had proper navigation properties, the query would be a simple:
var found= MyContext.FileAttachments.Any(f=>f.RecordType == 'item'
&& f.Item.Id = ThatItemID);
Without them, the LINQ query will have to JOIN the two "unrelated" entities:
var query = from item in MyContext.Items
join person in MyContext.FileAttachmentes
on file.RecordId equals item.ReferenceId
where item.ItemID == ThatId &&
file.RecordType == 'item'
select 1;
var found=query.Any();
The lack of navigation properties is a very strong sign that the model is wrong though.
A DbContext isn't a model of the database and doesn't have to mirror it. There's no need to have a single DbContext for the entire application either. Even if there are no Foreign Key Constraints between Items
and FileAttachments
it's possible to add relations between the classes
CodePudding user response:
AsNoTracking()
is used to prevent entity tracking by EF. Tracking allows EF to keep track of modifications made and on saving, these changes can be persisted. So, if a query doesn't need tracking (like a simple get query where no data change is persisted), we use AsNoTracking()
.
In your case, use navigation property if the entities are related instead of calling Context.Entity
. Also, AsNoTracking()
needs to specified only once in the query before loading the data.