Can I use join in Entity Framwork Pagination syntax? - c#

I was wondering if someone can help here.I'm new to Entity Framwork. I have 2 different Query.I want to join them and get 1.Here is my code:
public static List<BankDepositHistory> GetAllByPagination(int page ,int stepes)
{
page=page-1;
using(MyketAdsEntities context = new MyketAdsEntities())
{
var transactionlist = context.BankDepositHistories.ToList();
var start = page * stepes;
var result= context.BankDepositHistories.OrderByDescending(c=>c.AccountId)
//anny code that give me count as field
.Skip(start)
.Take(stepes)
.ToList();
return (result);
}
}
public static int GetCount()
{
using (MyketAdsEntities context = new MyketAdsEntities())
{
int count = context.BankDepositHistories.Count();
return count;
}
}
As you see I have 2 method. I just want to have GetAllByPagination.
Many thanks

Suppose you have below Entity, Then below setup should work.
public BankDepositHistory
{
public string UserName {get;set}
//etc..
}
Create a View Model
public class BankDepositHistoryVM
{
public List<BankDepositHistory> bankDetails {get;set;}
public int Count {get;set;}
}
Return View Model
public static List<BankDepositHistoryVM> GetAllByPagination(int page ,int stepes)
{
page=page-1;
using(MyketAdsEntities context = new MyketAdsEntities())
{
var transactionlist = context.BankDepositHistories.ToList();
var start = page * stepes;
var result= context.BankDepositHistories.OrderByDescending(c=>c.AccountId)
.Skip(start)
.Take(stepes)
.ToList();
List<BankDepositHistoryVM> resultVM = new List<BankDepositHistoryVM>();
resultVM.bankDetails = result;
resultVM.Count = result.Count();
return resultVM;
}
}
Call the method:
List<BankDepositHistory> bankDetails = className.GetAllByPagination.bankDetails;
int count = className.GetAllByPagination.Count;
List<BankDepositHistoryVM> allDetails = className.GetAllByPagination();
Hope helps.

Related

How to use InsertMany properly Mongodb C#

Hi I wont to pass some synthetic data to my database with the method InsertMany i have write the flowing code:
My Main:
static void Main(string[] args)
{
MongoCRUD db = new MongoCRUD("testClass");
List<GlobalUrbanPoint> syntheticData = CreateSunfeticData(20);
db.InsertMultipleRecords<GlobalUrbanPoint>("geo3", syntheticData);
}
My model class:
public class GlobalUrbanPoint
{
[BsonId]
public ObjectId Id{ get; set; }
public string NAME { get; set; }
}
The function for the synthetic data:
public static List<GlobalUrbanPoint> CreateSunfeticData(int NumberOfDocumet)
{
List<GlobalUrbanPoint> SyntheticList = new List<GlobalUrbanPoint>();
var SyntheticObject = new GlobalUrbanPoint();
for (var i = 1; i < NumberOfDocumet; i++)
{
SyntheticObject.NAME = (i+1).ToString();
SyntheticList.Add(SyntheticObject);
}
return SyntheticList;
}
And for my operation i use MongoCRUD
public class MongoCRUD
{
private IMongoDatabase db;
public MongoCRUD(string database)
{
var client = new MongoClient();
db = client.GetDatabase(database);
}
public void InsertRecord<T>(string table, T record)
{
var collection = db.GetCollection<T>(table);
collection.InsertOne(record);
}
public void InsertMultipleRecords<T>(string table, List<T> records)
{
var collection = db.GetCollection<T>(table);
collection.InsertMany(records);
}
}
When i run the code i get an error E11000 duplicate key error collection. I check the definition of InsertMany and it takes for arguments IEnumerable<TDocument> documents. It is an easy way to convert List<T> to IEnumerable<TDocument>?
What i need to change my synthetic function or my InsertMultipleRecords funtion. Any sugestion?
Thank you for your time.
After some digging i found that the object that i create in synthetic function has the same _id. For that i needed to change the creation of the object, inside of for loop. And my problem it was not in InsertMultipleRecords.
public static List<GlobalUrbanPoint> CreateSunfeticData(int NumberOfDocumet)
{
List<GlobalUrbanPoint> SyntheticList = new List<GlobalUrbanPoint>();
for (var i = 1; i < NumberOfDocumet; i++)
{
var SyntheticObject = new GlobalUrbanPoint();
SyntheticObject.NAME = (i+1).ToString();
SyntheticList.Add(SyntheticObject);
}
return SyntheticList;
}

EF 6 'Bulk' insert with FK relationed models

I am trying to bulk insert using EF (model first) on two tables that have a FK relationship (one to many). The code below properly inserts all of the Challenge entries but only inserts the X amount Shortages one time. My expectation... I have 10 shortages with 2 challenges. I should receive 2 challenge entries and 20 shortage entries. I am only seeing 10 challenge entries for the first shortage inserted. (the code below is simplified)
//class for cloning Shortage collection
public class ShortageCollection : Collection<Shortage>
{
public ShortageCollection(IList<Shortage> source) : base(source) { }
public ShortageCollection() { }
public ShortageCollection Clone()
{
return Clone(this);
}
public static ShortageCollection Clone(ShortageCollection shortage)
{
var res = new ShortageCollection();
foreach (var s in shortage)
{
res.Add(s.Clone());
}
}
}
public class Shortage : StandardDB.Shortage
{
public Shortage Clone()
{
return new Shortage()
{
PART_NUMBER = this.PART_NUMBER,
Note = this.Note,
Qty = this.Qty,
ResponseMachine = this.ResponseMachine
};
}
}
public void CreateChallenge()
{
var JSONJobs = new JavaScriptSerializer().Deserialize<string[]>(Jobs);
var JSONParts = new JavaScriptSerializer().Deserialize<ChallengePartsList[]>(Parts);
using (ARTEntities art = new ARTEntities())
{
art.Configuration.AutoDetectChangesEnabled = false;
art.Configuration.ValidateOnSaveEnabled = false;
ShortageCollection sColl = new ShortageCollection();
foreach(var part in JSONParts)
{
Shortage s = new Shortage()
{
PART_NUMBER = part.Invid,
Note = Challenge,
Qty = part.Qty,
ResponseMachine = ResponseMachine
};
sColl.Add(s);
}
foreach (var job in JSONJobs) {
Challenge c = new Challenge()
{
InitiatorORG = Org,
TypeID = TypeID,
DISCRETE_JOB = job,
InitiatorPERSON_ID = InitiatorPersonID,
InitiatedDate = datenow,
Challenge1 = Challenge,
ChampionGroupID = ChampionGroupID,
StatusID = StatusID,
InitiatorGroupID = InitiatorGroupID,
DivisionID = DivisionID,
Shortages = sColl.Clone()
};
art.Challenges.Add(c);
}
art.SaveChanges();
}
}
you are only creating 10 Shortages in memory. Your Clone method is a shallow clone, and doesn't go through and clone every object. Therefore you have 2 lists with 10 identical items (each pair of items point to exactly same memory reference).
What you need to do is DeepClone which is something like the following:
public static ShortageCollection Clone(ShortageCollection shortage)
{
var res = new ShortageCollection();
foreach(var s in shortage) {
res.Add( s.Clone() );
}
return res;
}
And in your shortage class:
public class Shortage
{
public Shortage Clone()
{
return new Shortage()
{
SomeProp = this.SomeProp,
SomeOtherProp = this.SomeOtherProp
}
}
}
Be aware that if inside shortage any of those objects point to another entity, each pair will point to the same entity.
Search for DeepClone for more info

How to built a dictionnary from linq query with Id as Key and Data Class as Value in c#?

I wish to built a dictionnary from a wcf service (this service is hosted on a server).
In my application, every 5 minutes, the distant user ask the service to get this dictionnary. This dictionnary will helps me to see if a message have been displayed on the userscreen with the help of the key.
I'm trying to get this result :
Key(alert_id), value1(alert_title,value2(alert_text)...
A dictionnary with Tuple seems to be a good solution, but I need help for the implementation.
public Dictionnary<int, Tuple<Alert>> GetAlertDataItems()
{
Dictionnary<int, Tuple<Alert>> AlertData = new Dictionnary<int, Tuple<Alert>>();
var q =
from p in db.AlertMap.Include(a=>a.AlertLog).Include(a=>a.AlertMode).Includ(a=>a.AlertPriority)
from t in db.RecipientMap
where ((p.AlertLog.AlertActive==true)&&(p.AlertID==t.AlertID)&&(DateTime.Now < p.AlertLog.AlertEndDate)
select p;
foreach (AlertMap singleAlert in q)
{...//I'm lost here
}
return AlertData;
}
Alert Class
[DataContract]
public class Alert
{
[DataMember]
public int AlertId {get;set;}
[DataMember]
public string AlertModeCde{get;set;}
[DataMember]
public string AlertPriorityCde {get;set;}
[DataMember]
public string AlertTitle{get;set;}
[DataMember]
public string AlertText{get;set;}
[DataMember]
public DateTime AlertStartDate {get;set;}
[DataMember]
public DateTime AlertEndDate {get;set;}
[DataMember]
public byte AlertActive {get;set;}
}
Thanks for any help !
Linq has a ToDictionary method built-in:
var AlertData = q.ToDictionary(a => a.AlertId, a => a);
in which case your return type should be Dictionnary<int, Alert>
Or to just extract the alert title and text into a Tuple:
var AlertData = q.ToDictionary(a => a.AlertId,
a => Tuple.Create(a.AlertTitle, a.AlertText));
in which case your return type should be Dictionnary<int, Tuple<string, string>>
You have to iterate on result and add items to dictionary one by one:
for(int i=0; i< q.Count(); i++)
{
AlertData.Add(i,new Tuple<Alert>(q[i]))
}
return AlertData;
Ok I have found a solution :
public Dictionnary<int,Alert>GetAlertDataItems()
{
Dictionnary<int,Alert> AlertDict = new Dictionnary<int,Alert>();
List<Alert> AlertData = new List<Alert>();
var q =
from p in db.AlertMap.Include(a=>a.AlertLog).Include(a=>a.AlertMode).Includ(a=>a.AlertPriority)
from t in db.RecipientMap
where ((p.AlertLog.AlertActive==true)&&(p.AlertID==t.AlertID)&&(DateTime.Now < p.AlertLog.AlertEndDate)
select p;
foreach(AlertMap singleAlert in q)
{
Alert a = new Alert();
a.AlertId = singleAlert.AlertID;
a.AlertTitle = singleAlert.AlertLog.AlertTitle;
....
AlertData.Add(a);
}
foreach(Alert alert in AlertData)
{
if(!AlertDict.Keys.Contains(alert.AlertId))
AlertDict.Add(alert.AlertId,alert);
}
return AlertDict;
}
It's not a perfect solution because I get my alertid field twice (one as key and another one in the values), but for testing, it's ok.
Thanks for help !

the binary expression cannot be converted to a predicate expression in LINQ

I want to get the week number of a certain given DateTime.
public static int WeekOf(DateTime? date)
{
if (date.HasValue)
{
GregorianCalendar gCalendar = new GregorianCalendar();
int WeekNumber = gCalendar.GetWeekOfYear(date.Value, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return WeekNumber;
}
else
return 0;
}
And then I use the above method in:
public static List<ExpressionListDictionary> MyMethod(int weeknr)
{
using (DataAccessAdapter adapter = CreateAdapter())
{
LinqMetaData meta = new LinqMetaData(adapter);
var q = (from i in meta.Test
where WeekOf(i.StartDate) == weeknr
select new ExpressionListDictionary()
{
{"SomeId", i.Id}
}
);
return q.ToList();
}
}
And finally:
List<ExpressionListDictionary> someIDs = MyMethod(weeknr);
/* weeknr = 19 -> step by step debugging */
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryConstructionException: The binary expression '(WeekOf(Convert(EntityField(LPLA_1.StartDate AS StartDate))) == 19)' can't be converted to a predicate expression.
I do get the title error at return q.ToList(); . How can I achieve this?
I haven't ever used the LLBLGen library/framework... But probably this is the same problem that happens with Entity Framework/LINQ-to-SQL: you can't put in a query C# methods: the query must be executed by your db server, not locally, and your db server doesn't know how to execute C# code. So the problem would be in the
**WeekOf(i.StartDate)** == weeknr part of code (that is the only BinaryExpression of your query)
The exception you have posted is quite clear that the point of the error is the one that I have suggested. Then the reason is probably the one I gave you.
Taken from https://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=22861
If you are using SQL Server, that supports DATEPART(isowk, ...) (or if you have MySQL, that supports WEEK(...))
public class SQLFunctionMappings : FunctionMappingStore
{
public SQLFunctionMappings()
{
Add(new FunctionMapping(
typeof(SQLFunctions),
"WeekOf",
1,
"DATEPART(isowk, {0})") // For SQL Server
// "WEEK({0}, 1)") For MySQL
);
}
}
public class SQLFunctions
{
public static int? WeekOf(DateTime? date)
{
return null;
}
}
and then you would use it like:
Where there is the row with LinqMetaData meta = new LinqMetaData(adapter), add:
meta.CustomFunctionMappings = new SQLFunctionMappings();
and change the where:
where SQLFunctions.WeekOf(i.StartDate) == weeknr
Here there is the list of the functions already mapped by llblgen, and how to map other functions.
you can try to Make the method you have WeekOf takes string instead of Datetime?
public static int WeekOf(String dateAsString)
{
//if (!string.IsNullOrEmpty(dateAsString))
if (!dateAsString.equals(string.empty))
{
GregorianCalendar gCalendar = new GregorianCalendar();
int WeekNumber = gCalendar.GetWeekOfYear(date.Value, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return WeekNumber;
}
else
return 0;
}
And then you use the above below in:
public static List<ExpressionListDictionary> MyMethod(int weeknr)
{
using (DataAccessAdapter adapter = CreateAdapter())
{
LinqMetaData meta = new LinqMetaData(adapter);
var q = (from i in meta.Test
where i.startDate != null && WeekOf(i.StartDate.tostring()) == weeknr
select new ExpressionListDictionary()
{
{"SomeId", i.Id}
}
);
return q.ToList();
}
}
Try something like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyMethod(5);
}
public static int WeekOf(DateTime? date)
{
if (date.HasValue)
{
GregorianCalendar gCalendar = new GregorianCalendar();
int WeekNumber = gCalendar.GetWeekOfYear(date.Value, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return WeekNumber;
}
else
return 0;
}
public static List<ExpressionListDictionary> MyMethod(int weeknr)
{
using (DataAccessAdapter adapter = CreateAdapter())
{
LinqMetaData meta = new LinqMetaData(adapter);
List<ExpressionListDictionary> q = (from i in meta.Test
where WeekOf(i.StartDate) == weeknr
select new ExpressionListDictionary()
{
Id = "SomeId"
}
).ToList();
return q;
}
}
public static DataAccessAdapter CreateAdapter()
{
return new DataAccessAdapter();
}
}
public class ExpressionListDictionary
{
public string Id { get; set; }
}
public class LinqMetaData
{
public List<LinqMetaData> Test {get;set;}
public DateTime StartDate {get;set;}
public int Id { get; set; }
public LinqMetaData(DataAccessAdapter adapter)
{
}
}
public class DataAccessAdapter : IDisposable
{
public void Dispose()
{
}
}
}
​

Returning two sets of action in one controller

So what i am doing is that i am displaying a list of categories in a page and each category contains a sublist of categories. I have a controller and it is returning the list of categories without the sublist of categories. how can i get the sublist showing from using the same controller.
Controller:
public CourseIndexVw Get(int id)
{
var _types = new ElementTypesService().GetElementModelsForCourseIndex(id, WebSecurity.CurrentUserId);
var _courseIndexbyTypesVw = new CourseSectionsControllerHelper().CourseIndexTypeVw(id);
_courseIndexbyTypesVw.Types = _types.ToList();
var _activeType = _courseIndexbyTypesVw.Types.First();
_courseIndexbyTypesVw.ActiveId = _activeType != null ? _activeType.Id : -1;
return _courseIndexbyTypesVw;
}
GetElementModelsForCourseIndex:
public List<ElementModelForCourseIndex> GetElementModelsForCourseIndex(int elementId, int userId, int depthLevel = 2)
{
List<ElementModelForCourseIndex> TypesName;
ElementType type;
using (var db = DataContextManager.AleStoredProcsContext)
{
TypesName = db.GetElementModelsForCourseIndex<ElementModelForCourseIndex>(elementId, userId, r => new ElementModelForCourseIndex{
Id = ElementsModelsForCourseIndexMap.Id(r),
Identity = ElementsModelsForCourseIndexMap.Identity(r)
}).OrderBy(n=>n.Identity).ToList();
}
foreach (ElementModelForCourseIndex typeContent in TypesName)
{
typeContent.Children = GetElementChildrenModelsForCourseIndex(elementId, userId, type.ModelId, depthLevel);
}
}
GetElementChildrenModelsForCourseIndex:
public List<ElementModelForCourseIndex> GetElementChildrenModelsForCourseIndex(int elementId, int userId, ElementType typeId, int depthLevel = 2)
{
using (var db = DataContextManager.AleStoredProcsContext)
{
return db.GetElementWithCalendarAndPermsByModel<ElementModelForCourseIndex>(elementId, userId, typeId.Id, r => new ElementModelForCourseIndex
{
IdentityName = ElementsModelsForCourseIndexMap.IdentityName(r),
ValueString = ElementsModelsForCourseIndexMap.ValueString(r),
TimeReleased = ElementsModelsForCourseIndexMap.TimeReleased(r),
TimeDue = ElementsModelsForCourseIndexMap.TimeReleased(r)
}).OrderBy(i => i.IdentityName).ToList();
}
}
UPDATE
Current issue is with typeContent.Children = GetElementChildrenModelsForCourseIndex(elementId, userId, type.ModelId, depthLevel); The error i am getting is: the override method has invalid arguments
Any Help is appreciated and if i am missing any information let me know. Thanks!
You can modify your model and add a children property:
public class ElementModelForCourseIndex
{
// *snip* your code
public List<ElementModelForCourseIndex> Children {get; set;}
}
You could either get it within your current GetElementModelsForCourseIndex or use you helper method like this:
public List<ElementModelForCourseIndex> GetElementModelsForCourseIndex(int elementId, int userId, int depthLevel = 2)
{
List<ElementModelForCourseIndex> courses;
using (var db = DataContextManager.AleStoredProcsContext)
{
courses = db.GetElementModelsForCourseIndex<ElementModelForCourseIndex>(elementId, userId, r => new ElementModelForCourseIndex{
Id = ElementsModelsForCourseIndexMap.Id(r),
Identity = ElementsModelsForCourseIndexMap.Identity(r)
}).OrderBy(n=>n.Identity).ToList();
}
for each(ElementModelForCourseIndex course in courses)
{
// here you are filling the Children.
//You need to check if the parameters are the correct ones.
// Since you haven't shown the actual model class, I'm only guessing the parameters
course.Children = GetElementChildrenModelsForCourseIndex(elementId, userId, depthLevel);
}
return courses;
}

Categories

Resources