MongoDB C# Driver Projection of fields - c#

Hi i have a collection In mongoDB that i want to get only part of the fields from it, i created a class that i'm inserting data with to Mongo
ClassCode:
public class FrameDocument
{
public ObjectId _id { get; set; }
public Nullable<System.DateTime> FrameTimeStamp { get; set; }
public Nullable<int> ActivePick { get; set; }
public Nullable<int> TraderId { get; set; }
public Nullable<int> EventCodeId { get; set; }
public byte[] Frame { get; set; }
public int ServerUserId { get; set; }
public int SesionId { get; set; }
public string TraderName { get; set; }
public string ServerUserName { get; set; }
}
This is the insert code:
FrameDocument frameDoc = new FrameDocument();
frameDoc.Frame = imageBA;
frameDoc.EventCodeId = 1;
frameDoc.SesionId = 1;
frameDoc.FrameTimeStamp = DateTime.Now;
frameDoc.ServerUserId = (int)toMongoDt.Rows[0]["ServerUserId"];
frameDoc.TraderId = (int)toMongoDt.Rows[0]["TraderId"];
frameDoc.ActivePick = (int)toMongoDt.Rows[0]["ActivePick"];
frameDoc.TraderName = (string)toMongoDt.Rows[0]["TraderName"];
frameDoc.ServerUserName = (string)toMongoDt.Rows[0] ["ServerUserName"];
var mongoCon = "mongodb://127.0.0.1";
MongoClient client = new MongoClient(mongoCon);
var db = client.GetDatabase("Video");
var frameCollection = db.GetCollection<FrameDocument>("Frame");
frameCollection.InsertOne(frameDoc);
**For now i get all The fields from the collection with this code, But i want to leave the Frame field out of the class, i tried to build different class without this field but i don't know how to not receive the Frame field **
var collection = db.GetCollection<BsonDocument>("Frame");
var builder = Builders<BsonDocument>.Filter;
var filter = builder.Eq("SesionId", 1)
& builder.Eq("TraderId", 125)
& builder.Eq("ServerUserId", 1)
& builder.Lt("FrameTimeStamp", sing.eDate)
& builder.Gt("FrameTimeStamp", sing.sDate);
var result = collection.Find(filter).ToList();
Can anyone help?

please see this:
_result = _collection.Find(o => o._id == _id)
.Project<FrameDocumentNoFrameField>
(Builders<FrameDocument>.Projection.Exclude(f => f.Frame)).ToList();
where FrameDocumentNoFrameField is a class without Frame field
source here

#Example: Model class
public class Company
{
public string CompanyId { get; set; }
public string CompanyName { get; set; }
public List<CompanySettings>{ get; set; }
}
[BsonIgnoreExtraElements]
public class CompanySettings
{
public CompanySetupType CompanySetupTypeId { get; set; }
public List<string> CompanyEmployee{ get; set; }
}
#Now create a Projection class for which you want to read values
[BsonIgnoreExtraElements]
public class CompanySettingsProjectionModel
{
public List<CompanySettings> CompanySettings { get; set; }
}
#After Creating projection,fetch data from mongo using Builders
public async Task<CompanySettings> GetCompanySettings(string companyId, short CompanySetupTypeId)
{
var filter = BaseFilter(accountId);
var projection = Builders<Company>.Projection
.Include(x => x.Id)
.Include(x => x.CompanySettings);
FindOptions<Company, CompanySettingsProjectionModel> findOptions = new FindOptions<Company, CompanySettingsProjectionModel>()
{
Projection = projection
};
var companySettings = await (await Collection.FindAsync(filter, findOptions)).FirstOrDefaultAsync();
if (companySettings != null && companySettings.CompanySettings != null && companySettings.CompanySettings.Any())
{
return companySettings.CompanySettings .FirstOrDefault(x => (int)x.CompanySetupTypeId == CompanySetupTypeId);
}
return default;
}

Related

Entity Framework Core Error when Adding a Join

how come this works:
var query = _context.Routing_Tool
.Where(rt => rt.Id == id)
.FirstOrDefault();
return query;
but this does not
var query = _context.Routing_Tool
.Join(_context.Routing_Tool_Prioritization_Matrix,
rt => rt.Id,
rp => rp.RoutingToolId,
(rt, rp) => new
{
Id = rt.Id,
Title = rt.Title,
LoeName = rp.LoeName,
}
)
.Where(rt => rt.Id == id)
.FirstOrDefault();
return query;
instead, I get and implicitly convert type error After I try to join a table. Help is appreciated
The whole new method - Including the old one I was working on for reference.
public Routing_Tool GetItemsInitById(int id)
{
//var query = (from rt in _context.Set<Routing_Tool>()
// join rp in _context.Set<Routing_Tool_Prioritization_Matrix>()
// on rt.Id equals rp.RoutingToolId into grouping
// from rp in grouping.DefaultIfEmpty()
// select new Routing_Tool {
// Id = rt.Id,
// Title = rt.Title,
// Classification = rt.Classification,
// MainPOC = rt.MainPOC,
// RequestingDirectorate = rt.RequestingDirectorate,
// IsEnduring = rt.IsEnduring,
// IsApproved = rt.IsApproved,
// IsAssociated = rt.IsAssociated,
// DirectingRequirement = rt.DirectingRequirement,
// RequirementDescription = rt.RequirementDescription,
// RequestType = rt.RequestType,
// // LoeName = rp.LoeName,
// // LoePriority = rp.LoePriority,
// }
// ).FirstOrDefault();
// return query;
var query = _context.Routing_Tool
.Join(_context.Routing_Tool_Prioritization_Matrix,
rt => rt.Id,
rp => rp.RoutingToolId,
(rt, rp) => new
{
Id = rt.Id,
Title = rt.Title,
}
)
.Where(rt => rt.Id == id)
.FirstOrDefault();
return query;
//return _context.Routing_Tool.FirstOrDefault(p => p.Id == id);
}
In the first case you the query variable is of IQueryable<Routing_Tool> type, which is right, you return it and everything is fine.
In the second case you return anonymous type and you have two options here:
Create a model for that type (with Id, Title and LoeName properties) and return "IQueryable< MyType >" instead
Return "Routing_Tool" from the expression ((rt, rp) => rt), which has no sense
I had to modify the Models for both tables by adding a collection, a new public method, a new select query:
public Routing_Tool GetItemsInitById(int id)
{
var initPage = _context.Routing_Tool
.Include(pub => pub.Routing_Tool_Prioritization_Matrices)
.Where(rt => rt.Id == id)
.FirstOrDefault();
return initPage;
}
routing tool model:
public class Routing_Tool
{
public Routing_Tool()
{
Routing_Tool_Prioritization_Matrices = new HashSet<Routing_Tool_Prioritization_Matrix>();
}
[Key]
[Required]
public int Id { get; set; }
[MaxLength(255)]
[Required]
public string Title { get; set; }
[MaxLength(255)]
[Required]
public string Classification { get; set; }
[MaxLength(255)]
[Required]
public string MainPOC { get; set; }
[MaxLength(10)]
[Required]
public string RequestingDirectorate { get; set; }
[MaxLength(1)]
[Required]
public int IsEnduring { get; set; }
[MaxLength(1)]
[Required]
public int IsApproved { get; set; }
[MaxLength(1)]
[Required]
public int IsAssociated { get; set; }
[Required]
public string DirectingRequirement { get; set; }
[Required]
public string RequirementDescription { get; set; }
[Required]
public string RequestType { get; set; }
public virtual ICollection<Routing_Tool_Prioritization_Matrix> Routing_Tool_Prioritization_Matrices { get; set; }
}
Dimensional table with FK:
public class Routing_Tool_Prioritization_Matrix
{
[Key]
[Required]
public int Id { get; set; }
public string LoeName { get; set; }
public string LoePriority { get; set; }
public int RoutingToolId { get; set; }
[ForeignKey("RoutingToolId")]
public virtual Routing_Tool Routing_Tool { get; set; }
}

Entity Framework to List without specific Column

I'm actually using EF and very new to it. I have a EDMX-Model from Database. I have to get a List of Entities, but in this Table is Binary-Column. I want my Object-List from that Table without the Binary Data.
My Entity-Objekt looks like:
public partial class bons
{
public int id { get; set; }
public System.DateTime zeitstempel { get; set; }
public byte[] bonBinaer { get; set; }
public Nullable<int> tisch_nr { get; set; }
public bool abgearbeitet { get; set; }
public int kunde_id { get; set; }
public string hash { get; set; }
public string dateiname { get; set; }
public string tisch_name { get; set; }
public int gang { get; set; }
public decimal brutto { get; set; }
public Nullable<System.DateTime> zeitstempelAbgearbeitet { get; set; }
public Nullable<int> positionenAnzahl { get; set; }
public bool manuell { get; set; }
}
And I#m getting the List like:
internal static List<bons> holeBongListeNichtAbgearbeitetRestaurant(int kunde_id)
{
List<bons> rückgabe = new List<bons>();
using (bonsEntities context = new bonsEntities())
{
rückgabe = context.bons.Where(x => x.kunde_id == kunde_id && x.abgearbeitet == false).OrderBy(x => x.zeitstempel).ToList();
}
return rückgabe;
}
Can someone help how to get the List without the 'byte[] bonBinaer'?
Hi you can use autoMapper with EF extension
like: https://docs.automapper.org/en/stable/Queryable-Extensions.html
or if you prefer you can do by yourself with a Select() method like:
using (bonsEntities context = new bonsEntities())
{
rückgabe = context.bons.Where(x => x.kunde_id == kunde_id && x.abgearbeitet == false).OrderBy(x => x.zeitstempel).Select(xx=> new {
id = xx.id
//and all you props
}).ToList().Select(yy=> new bons{
id=yy.id
//and back with other props
}).ToList();
}

WebAPI [FromBody] as EF Model behaves like it is immutable

I have an WebAPI Controller that uses complex types from Entity Framework. When I receive the object I check to see if it exists. If it doesn't I'd like to create a new. Before I create a new I'd like to add a couple additional values to the object. If I add a break point and a watch I can see the value and it appears like it has changed. But the value doesn't make it to the database.
[Authorize(Roles ="customerprofileuser")]
[Route("api/CustomerProfile/Save")]
[HttpPost]
public IHttpActionResult SaveCustomerProfile([FromBody] MERP.Customer _input)
{
Models.Message.Response _return = new Models.Message.Response();
_return.Message = "Profile Saved!";
_return.Now = DateTime.Now;
try {
ERPEntities ent = new ERPEntities();
var cust = ent.Customers.AsNoTracking().Where(w => w.ID == _input.ID).FirstOrDefault();
if (cust == null)
{
_input.ID = Guid.NewGuid();
_input.Alias = getCustomerNumberNext(_input.Type);
_input.CreatedOn = DateTime.Now;
ent.Customers.Add(_input);
}
else
{
ent.Customers.Attach(_input);
ent.Entry(_input).State = System.Data.Entity.EntityState.Modified;
}
_return.ResponseObject = _input.ID.ToString();
ent.SaveChanges();
}
catch (Exception ex)
{
_return.Message = ex.Message;
_return.Severity = 3;
}
return Ok(_return);
}
If I map the values to a new object like this, everything works as expected.
var val = new Customer();
val.ID = Guid.NewGuid();
val.Active = _input.Active;
val.Alias = getCustomerNumberNext(_input.Type);
val.CreatedOn = DateTime.Now;
ent.Customers.Add(val);
I'd rather not map every single property to the new object property. Is there a way around this behavior?
Here's a sample of the auto-generated Customer class from my Entity Model.
public partial class Customer
{
public System.Guid ID { get; set; }
public string Name { get; set; }
public Nullable<System.Guid> Type { get; set; }
public string Alias { get; set; }
public string Website { get; set; }
public string Note { get; set; }
public string Email { get; set; }
public Nullable<System.Guid> Salesman { get; set; }
public Nullable<System.Guid> SalesRegion { get; set; }
public Nullable<bool> Active { get; set; }
public string LinkedIn { get; set; }
public string Facebook { get; set; }
public string Twitter { get; set; }
public string GoldmineFK { get; set; }
public string SalesFK { get; set; }
public string InventoryFK { get; set; }
public Nullable<System.Guid> Industry { get; set; }
public Nullable<System.Guid> Lead { get; set; }
public Nullable<System.Guid> Show { get; set; }
public Nullable<System.Guid> Territory { get; set; }
public Nullable<System.DateTime> CreatedOn { get; set; }
}
Here's the getCustomerNumberNext function
private string getCustomerNumberNext(Guid? companyid)
{
ERPEntities ent = new ERPEntities();
var _prefix = (from p in ent.CompanyLookups
where p.Type == "CustomerNumberPrefix"
select p.Value.ToString()).FirstOrDefault();
var _number = (from p in ent.CompanyLookups
where p.Type == "CustomerNumberSequence"
select p.Value.ToString()).FirstOrDefault();
var _newNumber = Convert.ToInt32(_number) + 1;
try
{
var _update = (from p in ent.CompanyLookups
where p.Type == "CustomerNumberSequence"
select p).FirstOrDefault();
_update.Value = _newNumber.ToString();
ent.SaveChanges();
}
catch (Exception ex)
{ return ex.Message; }
return _prefix + _number;
}
EDIT: The C# code works as expected. The issue was with the data round tripping from the client and incompleteness.
I believe there is a typo in your question, which says "does make it to the database" but I believe you meant "does not make it to the database"
With that assumption I tried running similar code locally and was able to save the values as expected. The primary difference is that Alias is an integer in my code and I am assuming it is a complex class in your code. Here is the code that successfully saved the values to the database,
public class HomeController : ApiController
{
[HttpPost]
[Route("api/CustomerProfile/Save")]
public IHttpActionResult SaveCustomerProfile([FromBody] Customer _input)
{
masterEntities masterEntities = new masterEntities();
var cust = masterEntities.Customers.AsNoTracking().Where(w => w.ID == _input.ID).FirstOrDefault();
if (cust == null)
{
_input.ID = Guid.NewGuid();
_input.Alias = 0;
_input.CreatedOn = DateTime.Now;
masterEntities.Customers.Add(_input);
}
else
{
masterEntities.Customers.Attach(_input);
masterEntities.Entry(_input).State = System.Data.Entity.EntityState.Modified;
}
masterEntities.SaveChanges();
return Ok();
}
}
Here is what the generated Customer class like,
public partial class Customer
{
public System.Guid ID { get; set; }
public bool Active { get; set; }
public Nullable<int> Alias { get; set; }
public Nullable<System.DateTime> CreatedOn { get; set; }
}
Can you update your question with the Customer and Alias classes from your code and I can try reproducing that?
On a side note, I would suggest changing
var cust = ent.Customers.AsNoTracking().Where(w => w.ID == _input.ID).FirstOrDefault();
to
var cust = ent.Customers.AsNoTracking().FirstOrDefault(w => w.ID == _input.ID);

Convert to DTO list property

I have the following DTO:
public class QuestionGroupDTO : IBaseDTO
{
public string Description { get; set; }
public string Header { get; set; }
public Guid Id { get; set; }
public int Order { get; set; }
public IEnumerable<Services.Forms.Models.RelationForm_QuestionGroupDTO> RelationForms_QuestionGroups { get; set; }
public IEnumerable<RelationQuestionGroup_QuestionDTO> RelationQuestionGroups_Questions { get; set; }
}
I have problem with the RelationQuestionGroups_Questions while converting.
Here Is how my RelationQuestionGroup_QuestionDTO looks like
public class RelationQuestionGroup_QuestionDTO
{
public int Order { get; set; }
[Required]
public Guid QuestionGroupId { get; set; }
[Required]
public Guid QuestionId { get; set; }
public virtual QuestionGroupDTO QuestionGroup { get; set; }
public virtual QuestionDTO Question { get; set; }
}
Here Is how I convert:
public static QuestionGroupDTO ToDTO(this QuestionGroup src)
{
var dto = new QuestionGroupDTO
{
Id = src.Id,
Header = src.Header,
Description = src.Description,
RelationQuestionGroups_Questions = src.RelationQuestionGroups_Questions.ToList()
};
return dto;
}
As you can see, I'm trying to just assign It and make a list of It, but I got a casting error here. I'm not sure how to do this.
I get the following error:
Cannot implicity convert type Generic List to System.Collections.Generic.IEnumerble
You're having a great start at mapping, but at RelationQuestionGroups_Questions = src.RelationQuestionGroups_Questions.ToList(), you're trying to assign a List<Entity> to List<Dto>. You can't do that.
You need to map any non-primitive properties as well. You can do that like this:
public static QuestionGroupDTO ToDTO(this QuestionGroup src)
{
var dto = new QuestionGroupDTO
{
// ...
RelationQuestionGroups_Questions = src.RelationQuestionGroups_Questions
.Select(ToDTO)
.ToList()
};
return dto;
}
Then you add a method to map RelationQuestionGroups_Question to RelationQuestionGroups_QuestionDTO:
public RelationQuestionGroups_QuestionDTO ToDTO(RelationQuestionGroups_Question entity)
{
return new RelationQuestionGroups_QuestionDTO
{
Order = entity.Order,
// ...
};
}
And then you'll go look at AutoMapper to automate this.
You forgot to map RelationQuestionGroups_Questions to RelationQuestionGroup_QuestionDTO.
public static QuestionGroupDTO ToDTO(this QuestionGroup src)
{
var dto = new QuestionGroupDTO
{
Id = src.Id,
Header = src.Header,
Description = src.Description,
RelationQuestionGroups_Questions = src.RelationQuestionGroups_Questions.Select(rq => new RelationQuestionGroup_QuestionDTO
{
Order = rq.Order,
QuestionGroupId = rq.QuestionGroupId,
QuestionId = rq.QuestionId
}).ToList()
};
return dto;
}

Linq between class of table database and List<T>

I have a list of information that I keep in the session. Want a LINQ to join this this list and a table of the database.
The result is coming reset, nothing. What am I doing wrong?
Class of List:
public class ASOProcedimentoTemp
{
public int FuncionarioID { get; set; }
public int ProcedimentoID { get; set; }
}
Class of table database:
public class ASOProcedimento : IEntidadeBase
{
[Key]
public int ASOProcedimentoID { get; set; }
public int ASOID { get; set; }
[ForeignKey("ASOID")]
public virtual ASO ASO { get; set; }
public int ProcedimentoID { get; set; }
[ForeignKey("ProcedimentoID")]
public virtual Procedimento Procedimento { get; set; }
public DateTime DtProcedimento { get; set; }
}
My LINQ:
var dadosTemp = HttpContext.Current.Session["ASOProcedimentoTemp"] as List<ASOProcedimentoTemp>;
if (dadosTemp == null)
dadosTemp = new List<ASOProcedimentoTemp>();
result =
(from a in dados.AsQueryable()
join b in dadosTemp on a.ProcedimentoID equals b.ProcedimentoID
select new
{
a.ProcedimentoID,
a.Procedimento.Descricao
})
.Where(where, filtro)
.OrderBy(orderna + " " + ordenaTipo);
The Contains will cause a SQL Where In clause with your IDs in your sql call.
var dadosTemp = HttpContext.Current.Session["ASOProcedimentoTemp"] as List<ASOProcedimentoTemp>;
if (dadosTemp == null)
dadosTemp = new List<ASOProcedimentoTemp>();
var procedimentoIDs = dadosTemp.Select(a => a.ProcedimentoID).ToList();
result =
(from a in dados
where procedimentoIDs.Contains(a.ProcedimentoID)
select new
{
a.ProcedimentoID,
a.Procedimento.Descricao
});

Categories

Resources