Linq where with nested .Any() in string variable - c#

These are my entities:
public class Subscription : BaseItem
{
public virtual DateTime DateStart { get; set; }
public virtual DateTime? DateEnd { get; set; }
public virtual int Status { get; set; }
public virtual Account Account { get; set; }
public virtual Theater Theater { get; set; }
public virtual Agent Agent { get; set; }
}
public class Account : BaseItem
{
public virtual string LegalName { get; set; }
public virtual string FirstName { get; set; }
public virtual string UrlName { get; set; }
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
public virtual string ZipCode { get; set; }
public virtual string Country { get; set; }
public virtual string Tel { get; set; }
public virtual string Tel2 { get; set; }
public virtual string Fax { get; set; }
public virtual string Mobile { get; set; }
public virtual string Email { get; set; }
public virtual string Website { get; set; }
public virtual int DefaultVatRate { get; set; }
public virtual bool Bankrupt { get; set; }
public virtual string ExternalId { get; set; }
public virtual bool DoNotContact { get; set; }
public virtual bool NotInterested { get; set; }
public virtual Group Group { get; set; }
public virtual IList<Header> Headers { get; set; }
public virtual IList<Note> Notes { get; set; }
public virtual IList<Order> Orders { get; set; }
public virtual IList<Subscription> Subscriptions { get; set; }
}
public class Order : BaseItem
{
public virtual int Number { get; set; }
public virtual DateTime Date { get; set; }
public virtual string Description { get; set; }
public virtual double Amount { get; set; }
public virtual string Attachment { get; set; }
public virtual string AttachmentFilename { get; set; }
public virtual string AttachmentMimetype { get; set; }
public virtual bool? PaidToTheater { get; set; }
public virtual DateTime? DatePaidToTheater { get; set; }
public virtual bool? CashinByTheater { get; set; }
public virtual Account Account { get; set; }
public virtual Theater Theater { get; set; }
public virtual Agent Agent { get; set; }
public virtual IList<Invoice> Invoices { get; set; }
public virtual IList<OrdersAttachment> OrdersAttachments { get; set; }
public virtual IList<OrdersDueDate> OrdersDueDates { get; set; }
public virtual Header Header { get; set; }
}
public class Invoice : BaseItem
{
public virtual int Number { get; set; }
public virtual DateTime Date { get; set; }
public virtual double Amount { get; set; }
public virtual double VatRate { get; set; }
public virtual bool IsDisabled { get; set; }
public virtual bool IsSendMail { get; set; }
public virtual Order Order { get; set; }
public virtual IList<InvoicesDueDate> InvoicesDueDates { get; set; }
public virtual IList<InvoicesPayment> InvoicesPayments { get; set; }
}
I have a method in my program that build a "query" in a string variable.
private string GenerateQuery(FilterSubscription filterSubscription)
{
if (filterSubscription.FilterByOrder)
return "Account.Orders.Any()";
if (filterSubscription.FilterByInvoice)
return "Account.Orders.Any(Invoices.Any())"; //here is my problem
}
This is the call to the method
string query = GenerateQuery(filterSubscription)
var count = Session.Linq<Subscription>().Where(query).Count();
If I need to extract all accounts that have at least one Order is all OK.
But if I need to extract all accounts that have at least one Invoice I don't know how.
If I wrote
var count = Session.Linq<Subscription>().Where(s=>s.Account.Orders.Any(o=>o.Invoices.Any())).Count();
it works but if I use the string variable it doesn't.

It looks like you should return a delegate from GenerateQuery instead - something like:
private Expression<Func<Subscription, bool>> GenerateQuery(FilterSubscription filterSubscription)
{
if (filterSubscription.FilterByOrder)
return s => s.Account.Orders.Any();
if (filterSubscription.FilterByInvoice)
return s => s.Account.Orders.Any(o => o.Invoices.Any());
}
Then just update the query variable to be implicitly typed:
var query = GenerateQuery(filterSubscription);

Related

NHibernate Left Join

A very beginner question:
I have two classes, Review and ReviewSentences:
public class Review
{
public virtual int recordId { get; set; }
public virtual string reviewerId { get; set; }
public virtual string reviewerName { get; set; }
public virtual string country { get; set; }
public virtual string zipCode { get; set; }
public virtual string reviewProduct { get; set; }
public virtual string reviewText { get; set; }
public virtual string reviewTextLanguage { get; set; }
public virtual double sentimentScore { get; set; }
public virtual bool isScoreRefined { get; set; }
}
pulic class ReviewSentences
{
public virtual int recordId { get; set; }
public virtual int reviewId { get; set; }
public virtual int sentenceId { get; set; }
public virtual string sentence { get; set; }
public virtual double sentimentScore { get; set; }
}
The property ReviewSentences.reviewId is a foreign key referring to Review.recordId. One review can have many sentences (Review:ReviewSentences is 1:Many)
I have been trying for a long time now but unable to replicate the following query in terms of NHibernate with session.CreateCriteria:
select * from Reviews r
left join
ReviewSentences rs
on
r.RecordId = rs.ReviewId
where rs.ReviewId is null
The query gives me all reviews from the Review table that do not have any records in the ReviewSentences table.
It is a matter of mapping you should include an array of ReviewSentences in your Review class and map it correctly.
public class Review
{
public virtual int recordId { get; set; }
public virtual string reviewerId { get; set; }
public virtual string reviewerName { get; set; }
public virtual string country { get; set; }
public virtual string zipCode { get; set; }
public virtual string reviewProduct { get; set; }
public virtual string reviewText { get; set; }
public virtual string reviewTextLanguage { get; set; }
public virtual double sentimentScore { get; set; }
public virtual bool isScoreRefined { get; set; }
public virtual IList<ReviewSentences> sentences { get; set; }
}
pulic class ReviewSentences
{
public virtual int recordId { get; set; }
public virtual int reviewId { get; set; }
public virtual int sentenceId { get; set; }
public virtual string sentence { get; set; }
public virtual double sentimentScore { get; set; }
}
then in the mapping you should refer sentences as a reference.
but you did not said which kind of mapping your using (Fluent, conformist, etc.)
Fixed the mapping in hbm.xml files and got the required results using:
var reviews= session.CreateCriteria<Review>("r")
.CreateCriteria("r.sentences", JoinType.LeftOuterJoin)
.Add(Restrictions.IsNull("recordId"))
.List<Review>();

EF6 Code First -relationship may cause cycles or multiple cascade paths

Introducing FOREIGN KEY constraint 'FK_dbo.Queries_dbo.Users_UserID' on table 'Queries' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.
public partial class User
{
public User()
{
this.Alerts = new HashSet<Alert>();
this.DeviceTokens = new HashSet<DeviceToken>();
this.MobileNotifications = new HashSet<MobileNotification>();
this.Queries = new HashSet<Query>();
this.SendQueries = new HashSet<SendQuery>();
}
public int ID { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string SSOID { get; set; }
public Nullable<System.DateTime> LastLogin { get; set; }
public int LatestUpdatedRecord { get; set; }
public virtual ICollection<Alert> Alerts { get; set; }
public virtual ICollection<DeviceToken> DeviceTokens { get; set; }
public virtual ICollection<MobileNotification> MobileNotifications { get; set; }
public virtual ICollection<Query> Queries { get; set; }
public virtual ICollection<SendQuery> SendQueries { get; set; }
}
public partial class Query
{
public Query()
{
this.AlertEmails = new HashSet<AlertEmail>();
this.Alerts = new HashSet<Alert>();
this.QueryFacets = new HashSet<QueryFacet>();
}
public int ID { get; set; }
public int UserID { get; set; }
public string EntityType { get; set; }
public string Name { get; set; }
public string SearchTerm { get; set; }
public string OrderBy { get; set; }
public string QueryType { get; set; }
public string ReceiveUpdateTime { get; set; }
public Nullable<System.DateTime> NextSendTime { get; set; }
public bool IsActive { get; set; }
public string Token { get; set; }
public string AlertName { get; set; }
public bool Enabled { get; set; }
public bool GetNotifications { get; set; }
public string TimeFilterType { get; set; }
public string TimeFilterValue { get; set; }
public string RectangleFilter { get; set; }
public virtual ICollection<AlertEmail> AlertEmails { get; set; }
public virtual ICollection<Alert> Alerts { get; set; }
public virtual ICollection<QueryFacet> QueryFacets { get; set; }
public virtual User User { get; set; }
}
public partial class SearchAndAlertDbContext : DbContext
{
public virtual DbSet<AlertEmail> AlertEmails { get; set; }
public virtual DbSet<AlertingTime> AlertingTimes { get; set; }
public virtual DbSet<Alert> Alerts { get; set; }
public virtual DbSet<DeviceToken> DeviceTokens { get; set; }
public virtual DbSet<IgnoredSlide> IgnoredSlides { get; set; }
public virtual DbSet<Log> Logs { get; set; }
public virtual DbSet<MobileNotification> MobileNotifications { get; set; }
public virtual DbSet<Query> Queries { get; set; }
public virtual DbSet<QueryFacet> QueryFacets { get; set; }
public virtual DbSet<SendQuery> SendQueries { get; set; }
public virtual DbSet<StoredQuery> StoredQueries { get; set; }
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<BlockedUserForActivity> BlockedUserForActivities { get; set; }
public virtual DbSet<UserActivity> UserActivities { get; set; }
public virtual DbSet<UserActivityIgnoreList> UserActivityIgnoreLists { get; set; }
public virtual DbSet<UserActivityMonitor> UserActivityMonitors { get; set; }
public virtual DbSet<UserActivitySpecificSetting> UserActivitySpecificSettings { get; set; }
public virtual DbSet<WarnedUserForActivity> WarnedUserForActivities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().
HasMany(p => p.Queries).
WithRequired(a => a.User).
HasForeignKey(a => a.UserID).WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
}
Tell EF not to cascade the query delete.
modelBuilder.Entity<Query>()
.HasRequired(q => q.User)
.WithMany(s => s.Queries)
.HasForeignKey(s => s.UserId)
.WillCascadeOnDelete(false);
Or turn off the convention:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

How can change grouped List<MyClass> to list<MyAnotherClass> type?

Here is my codes;
public List<SbtKlasorViewModel> GetFoldersWithIndexedDocuments()
{
//TODO - I can't find right query. We need folders with documents but only documents which be Indexed
using (ISession session = DatabaseProvider.SessionFactory.OpenSession())
{
List<DokumanlarModel> dokumanList = session.QueryOver<DokumanlarModel>()
.Where(x => x.IndexlenmeTarihi != null)
.List().ToList();
var list = dokumanList.GroupBy(x => x.Klasor.Aciklama);
List<SbtKlasorModel> folders = list as List<SbtKlasorModel>;
////Transforming SbtKlasorModel to SbtKlasorViewModel for respose
List<SbtKlasorViewModel> transformedFolders = folders
.Select(x => ModelTransformer.TransformModel(x)).ToList();
return transformedFolders;
}
}
DokumanlarModel.cs:
public class DokumanlarModel : SModuleClass
{
public virtual int DokumanId { get; set; }
public virtual string DokumanAdi { get; set; }
public virtual int DosyaBoyutu { get; set; }
public virtual int Durum { get; set; }
public virtual string EskiPath { get; set; }
public virtual string IndexTahsisKullanici { get; set; }
public virtual DateTime? IndexlenmeTarihi { get; set; }
public virtual string IndexleyenKullanici { get; set; }
public virtual string KaliteKontrolKullanici { get; set; }
public virtual DateTime? KaliteKontrolTarihi { get; set; }
public virtual SbtKlasorModel Klasor { get; set; }
public virtual int KlasordekiSira { get; set; }
public virtual DokNitelikTipModel NitelikTipId { get; set; }
public virtual int OcrDurum { get; set; }
public virtual string Path { get; set; }
public virtual int SayfaSayisi { get; set; }
public virtual DateTime? TaranmaTarihi { get; set; }
public virtual string TarayanKullanici { get; set; }
public virtual int Versiyon { get; set; }
public virtual string OrjinalPath { get; set; }
public virtual IList<LogDokumanModel> LogDokumanList { get; set; }
public virtual IList<DokumanlarOcrModel> DokumanlarOcrList { get; set; }
public virtual IList<DokVersiyonModel> DokVersiyonList { get; set; }
public virtual IList<DokMetaDataArsivModel> DokMetaDataArsivList { get; set; }
public DokumanlarModel()
{
LogDokumanList = new List<LogDokumanModel>();
DokumanlarOcrList = new List<DokumanlarOcrModel>();
DokVersiyonList = new List<DokVersiyonModel>();
DokMetaDataArsivList = new List<DokMetaDataArsivModel>();
}
}
SbtKlasorModel.cs:
public class SbtKlasorModel : SModuleClass
{
public virtual int KlasorId { get; set; }
public virtual string Aciklama { get; set; }
public virtual string Ada { get; set; }
public virtual string KisiAdSoyad { get; set; }
public virtual string Mahalle { get; set; }
public virtual string Parsel { get; set; }
public virtual string SerhAciklama { get; set; }
public virtual DateTime SerhBaslangicTarihi { get; set; }
public virtual DateTime SerhBitisTarihi { get; set; }
public virtual SbtKullaniciModel SerhKullanici { get; set; }
public virtual string Pafta { get; set; }
public virtual string KlasorNo { get; set; }
public virtual string SiraNo { get; set; }
public virtual string AciklamaYeni { get; set; }
public virtual IList<IlskGrupKlasorModel> IlskGrupKlasorList { get; set; }
public virtual IList<DokumanlarModel> DokumanlarList { get; set; }
public virtual IList<DokTaleplerModel> DokTaleplerList { get; set; }
public SbtKlasorModel()
{
IlskGrupKlasorList = new List<IlskGrupKlasorModel>();
DokumanlarList = new List<DokumanlarModel>();
DokTaleplerList = new List<DokTaleplerModel>();
}
}
I got data like List from database. And grouped by "DokumanlarModel.Klasor.Aciklama". But I need List list. I tried like above. It returns null. What should i do for this type change?
public List<SbtKlasorViewModel> GetFoldersWithIndexedDocuments()
{
using (var session = DatabaseProvider.SessionFactory.OpenSession())
{
var foldersContainingIndexedDocs = session.QueryOver<SbtKlasorModel>()
.JoinQueryOver<DokumanlarModel>(x => x.DokumanlarList)
.Where(doc => doc.IndexlenmeTarihi != null)
.List();
//Transforming SbtKlasorModel to SbtKlasorViewModel for respose
return folders.Select(ModelTransformer.TransformModel).ToList();
}
}

How to use Fluent API to map foreign key

I am trying to use modelBuilder to map a foreign Key in my database. I need to post the Id into JobTESPM_EmployeeId instead of JOBTESPMId. I have been using this a guide but I can't see where the examples are the same as my setup. http://msdn.microsoft.com/en-in/data/jj591620.aspx#IndependentAssociation
public class Job
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
public Int64? JobId { get; set; }
public int? JobNumber { get; set; }
public string JobName { get; set; }
public int? JobTypeId { get; set; }
public int? CustomerEmployeePMId { get; set; }
public virtual CustomerEmployee CustomerEmployeePM { get; set; }
public int? CustomerEmployeeAdminId { get; set; }
public virtual CustomerEmployee CustomerEmployeeAdmin { get; set; }
public int? CustomerEmployeeAccountantId { get; set; }
public virtual CustomerEmployee CustomerEmployeeAccountant { get; set; }
public int? CustomerEmployeeSuperintendentId { get; set; }
public virtual CustomerEmployee CustomerEmployeeSuperintendent { get; set; }
public int? JobTESPMId { get; set; }
public virtual Employee JobTESPM { get; set; }
public int? JobTESSuperintendentId { get; set; }
public virtual Employee JobTESSuperintendent { get; set; }
}
public class Employee
{
public int EmployeeId { get; set; }
public string AccountName { get; set; }
public string EmployeeFirstName { get; set; }
public string EmployeeLastName { get; set; }
public string EmployeeTitle { get; set; }
public Int64? EmployeeCellPhone { get; set; }
public Int64? EmployeeOfficePhone { get; set; }
public string EmployeeEmail { get; set; }
public int? CompanyEmployeeId { get; set; }
public bool? EmployeeHidden { get; set; }
public bool? EmployeeIsSuper { get; set; }
public bool? EmployeeIsPM { get; set; }
public string EmployeeAltEmail { get; set; }
}
What about adding a couple attributes...
[Column("JobTESPM_EmployeeID")]
public int? JobTESPMId { get; set; }
[ForeignKey("JobTESPMId")]
public virtual Employee JobTESPM { get; set; }

Why is a new object not saved when adding it to a list of an existing object in EF4?

I retrieve an existing customer from the database by it's id. This customer has a list of certificates. So I have: customer.CertificatesAsInvestor.
When I create a new certificate (var cert = new Certificate()) and add this object to the list customer.CertificatesAsInvestor.Add(cert) and then call SaveChanges(), the new certificate is not stored in the Database.
Why is this and what do I have to do to get this to work?
Customer class:
public partial class Customer
{
public Customer()
{
this.Deceased = false;
this.CertificatesAsInvestor = new HashSet<Certificate>();
this.CertificatesAsBeneficiary = new HashSet<Certificate>();
this.BankAccounts = new HashSet<BankAccount>();
this.Notes = new HashSet<Note>();
this.Documents = new HashSet<Document>();
this.Name = new PersonName();
}
public int Id { get; set; }
public string Code { get; set; }
public string CompanyName { get; set; }
public string EmailAddress { get; set; }
public System.DateTime BirthDate { get; set; }
public string BSNNo { get; set; }
public string IdCardNo { get; set; }
public bool Deceased { get; set; }
public Kompas.Bas.Gender Gender { get; set; }
public Kompas.Bas.Title Title { get; set; }
public string DayPhone { get; set; }
public string OtherPhone { get; set; }
public Kompas.Bas.CustomerStatus Status { get; set; }
public PersonName Name { get; set; }
public virtual Address Address { get; set; }
public virtual ICollection<Certificate> CertificatesAsInvestor { get; set; }
public virtual ICollection<Certificate> CertificatesAsBeneficiary { get; set; }
public virtual Address PostalAddress { get; set; }
public virtual ICollection<BankAccount> BankAccounts { get; set; }
public virtual ICollection<Note> Notes { get; set; }
public virtual ICollection<Document> Documents { get; set; }
}
Certificate:
public partial class Certificate
{
public Certificate()
{
this.Transactions = new HashSet<Transaction>();
this.Notes = new HashSet<Note>();
this.Clicks = new HashSet<Click>();
this.ParticipationCalculations = new HashSet<ParticipationCalculation>();
}
public int Id { get; set; }
public int CertificateNo { get; set; }
public decimal NominalFee { get; set; }
public bool IsSigned { get; set; }
public System.DateTime DateIn { get; set; }
public Nullable<System.DateTime> ReturnDate { get; set; }
public Nullable<System.DateTime> OrderDate { get; set; }
public Nullable<System.DateTime> DateStop { get; set; }
public Kompas.Bas.Paymethod Paymethod { get; set; }
public Kompas.Bas.CertificateStatus Status { get; set; }
public Nullable<int> DexContractNumber { get; set; }
public Nullable<int> CollectionId { get; set; }
public Nullable<System.DateTime> FinalDateMin { get; set; }
public Nullable<System.DateTime> FinalDateMax { get; set; }
public bool Gift { get; set; }
public decimal PurchaseRate { get; set; }
public decimal PurchaseRateDiscount { get; set; }
public Nullable<System.DateTime> PayStopDate { get; set; }
public decimal GuaranteeValue { get; set; }
public int PaidTermCount { get; set; }
public decimal DepositNominal { get; set; }
public string SecondName { get; set; }
public Nullable<System.DateTime> SecondBirthDate { get; set; }
public virtual Customer InvestingCustomer { get; set; }
public virtual Customer BeneficiaryCustomer { get; set; }
public virtual InvestorRole InvestorRole { get; set; }
public virtual Product Product { get; set; }
public virtual BankAccount CollectionBankAccount { get; set; }
public virtual BankAccount PaymentBankAccount { get; set; }
public virtual Origin Origin { get; set; }
public virtual ICollection<Transaction> Transactions { get; set; }
public virtual ICollection<Note> Notes { get; set; }
public virtual ICollection<Click> Clicks { get; set; }
public virtual ICollection<ParticipationCalculation> ParticipationCalculations { get; set; }
}

Categories