public class Account
{
[Key]
[StringLength(80)]
public string AccountID { get; set; } = string.Empty;
[StringLength(255)]
public string Name { get; set; } = string.Empty;
[ForeignKey(nameof(AccountID))]
public virtual ICollection<Relation> Relations { get; set; }
}
public class Role
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public long RoleID { get; set; } = -1;
[StringLength(80)]
public string RoleName { get; set; } = string.Empty;
}
public class Relation
{
[Key]
[StringLength(80)]
public string AccountID { get; set; } = string.Empty;
[Required]
public long RoleID { get; set; } = 0;
[ForeignKey(nameof(RoleID))]
public virtual Role Role { get; set; }
}
public class AccountsController : ODataController
{
private readonly DS2DbContext _context;
public AccountsController(DS2DbContext context)
{
_context = context;
}
[EnableQuery(PageSize = 20)]
public IQueryable<Account> Get()
{
return _context.Accounts;
}
[EnableQuery]
public SingleResult<Account> Get([FromODataUri] string ID)
{
var result = _context.Accounts.Where(
e => string.Compare(e.AccountID, ID, StringComparison.InvariantCultureIgnoreCase) == 0);
return SingleResult.Create(result);
}
}
The controller is called by a grid which is querying a list of Account records as well as code that reads a single Account record with a given account id.
List query:
https://localhost:44393/DS/Accounts?$count=true&$expand=UserInfo,Relations($expand=Role)&$skip=0&$top=20
Single record query:
https://localhost:44393/DS/Accounts('bt0388')?$expand=UserInfo,Relations($expand=Role)
As long as the SingleResult<Account> Get() method is commented out, the list query ends up in IQueryable<Account> Get() as it should and the query works fine.
As soon as I uncomment SingleResult<Account> Get(), the list query ends up in the SingleResult<Account> Get() and fails.
The single record query never reaches SingleResult<Account> Get(). Omitting the $expand parameter doesn't change anything.
What is going wrong here, and how do I fix it?
Related
The role property of a relation record doesn't get read/initialized (i.e. the data from the included table doesn't get read). Why is that? The data is in the database.
public class IDM_Role
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public long role_id { get; set; } = -1;
[StringLength(80)]
public string role_name { get; set; } = string.Empty;
}
public class IDM_Relation
{
[Required]
[StringLength(80)]
public string account_id { get; set; } = string.Empty;
[Required]
[ForeignKey("IDM_Role")]
public long role_id { get; set; } = 0;
[ForeignKey("role_id")]
public virtual IDM_Role role { get; set; }
}
modelBuilder.Entity<IDM_Relation>()
.HasKey(e => new { e.role_id, e.account_id })
.HasName("PK_IDM_Relation");
[EnableQuery(PageSize = 15)]
public IQueryable<IDM_Relation> Get()
{
return _context.idm_relations.Include(e => e.role);
}
Removing "virtual" from the property IDM_Role role doesn't help.
I have two sets of codes. The first one doesn't give me the list of data but the second on does. Please see codes below:
First Code:
Model
public class Student
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
}
DataConnection
public class DataConnection : DbContext
{
public DataConnection()
: base("DefaultConnection")
{
}
public DbSet<Student> Students { get; set; }
}
Interface
public interface IStudent
{
List<Student> StudentList();
void InsertStudent(Student student);
void UpdateStudent(Student student);
Student GetStudentById(int id);
void DeleteStudent(int id);
}
Concrete
readonly DataConnection _context;
public StudentConcrete()
{
_context = new DataConnection();
}
public List<Student> StudentList()
{
var studentList = (from s in _context.Students select s).ToList();
return studentList;
}
Second Code
Concrete
readonly DataConnection _context;
public StudentConcrete()
{
_context = new DataConnection();
}
public List<Student> StudentList()
{
SqlConnection xxx = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
var cmd = new SqlCommand("GetAllStudents", xxx);
var da = new SqlDataAdapter(cmd);
var ds = new DataSet();
da.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
return (from DataRow row in ds.Tables[0].Rows
select new Student()
{
Age = Convert.ToInt32(row["Age"]),
FirstName = row["FirstName"].ToString(),
Gender = row["Gender"].ToString(),
LastName = row["LastName"].ToString()
}).ToList();
}
else
{
return null;
}
}
I would like to get the data using the first code but I don't know where I get it wrong. My SP is just to get the students.
I suspected that maybe you are retrieving the records from another table somehow. Would you try to add Table attribute for Student entity.
using System.ComponentModel.DataAnnotations.Schema;
[Table("Students")]
public class Student
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
}
I'm new to Entity Framework. At the moment I'm having a problem - when I try to insert a new User object into the database (using method RegisterNewUser), I keep getting an error:
Violation of PRIMARY KEY constraint 'PK__Users__3214EC07705D23AE'. Cannot insert duplicate key in object 'dbo.Users'. The duplicate key value is (0).
There are some similar questions here, but none of these answers have helped me.
public void RegisterNewUser(String uName, String uPass, String fName, String lName, String email)
{
User user = new User();
user.Username = uName;
user.Password = uPass;
user.FirstName = fName;
user.LastName = lName;
user.Email = email;
Time time = new Time();
time.Time1 = DateTime.Now;
user.Times.Add(time);
ur.AddUser(user);
}
Time and User objects:
public partial class Time
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int UserId { get; set; }
public System.DateTime Time1 { get; set; }
public virtual User User { get; set; }
}
public partial class User
{
public User()
{
this.Times = new HashSet<Time>();
}
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public virtual ICollection<Time> Times { get; set; }
}
Repository file
public class UsersRepository
{
UsersDBContext userDBContext = new UsersDBContext();
public List<User> GetUsers()
{
return userDBContext.Users.Include("Times").ToList();
}
public void AddUser(User user)
{
userDBContext.Users.Add(user);
userDBContext.SaveChanges();
}
}
And context
public partial class UsersDBContext : DbContext
{
public UsersDBContext() : base("name=UsersDBContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Time> Times { get; set; }
public virtual DbSet<User> Users { get; set; }
}
I have no idea how to solve this so any suggestions would be very helpful
set a value of Id field
or
define the Id field as autoincrement
Using code first (EF 6), I created a 1 parent - 2 child relationship. Property is the parent object and Property Address as a child with 1 or 0..1 relationship. PropertyImage is another child with 1 to many relationship. PropertyImage works fine but the PropertyAddress throws error if I try to eager load .
Actual Error -
Multiplicity constraint violated.
The role 'PropertyAddress_Property_Source' of the relationship 'MyAssetTracker.DataLayer.Models.PropertyAddress_Property' has multiplicity 1 or 0..1.
// Test Function
GetProperty()
{
Property property;
using (var repo = new PropertyRepository())
{
property = repo.AllIncluding(a=>a.Images, a=>a.Address).FirstOrDefault(a => a.Id == testpropertyid);
}
}
//Property Repository
public class PropertyRepository : IPropertyRepository
{
public IQueryable<Property> AllIncluding(params Expression<Func<Property, object>>[] includeProperties)
{
IQueryable<Property> query = context.Properties;
foreach (var includeProperty in includeProperties) {
query = query.Include(includeProperty);
}
return query;
}
}
//Property Entity
public class Property : DomainModelAuditBase, IDomainModelState
{
private Address _address;
private ICollection<Asset> _assets;
private ICollection<PropertyImage> _images;
public Property()
{
_address = new Address();
_assets = new List<Asset>();
_images = new List<PropertyImage>();
}
public Guid Id { get; set; }
[StringLength(100), Required]
public string Title { get; set; }
public bool IsPrimary { get; set; }
[StringLength(255)]
public string Description { get; set; }
[NotMapped]
public State State { get; set; }
public Guid AddressId { get; set; }
public Guid UserId { get; set; }
public virtual Address Address
{
get { return _address; }
set { _address = value; }
}
public virtual ICollection<Asset> Assets
{
get { return _assets; }
set { _assets = value; }
}
public virtual User User { get; set; }
public virtual ICollection<PropertyImage> Images
{
get { return _images; }
set { _images = value; }
}
}
//PropertyAddress
public class Address : DomainModelAuditBase, IDomainModelState
{
[Key,ForeignKey("Property")]
public Guid PropertyId { get; set; }
[StringLength(255),Required]
public string AddressLine1 { get; set; }
[StringLength(255)]
public string AddressLine2 { get; set; }
[StringLength(255)]
public string City { get; set; }
[StringLength(255)]
public string StateProvince { get; set; }
[StringLength(100)]
public string PostalCode { get; set; }
[StringLength(100)]
public string Country { get; set; }
[NotMapped]
public State State { get; set; }
public virtual Property Property { get; set; }
}
Remove_address = new Address(); from Property constructor.
You could read about similar problem here
Also are you sure that you need AddressId field in Property class?
Beginner with entity framework and mvc here.
I have 2 table models:
UserProfile
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
}
and
ChatLogs
[Table("ChatLogs")]
public class ChatLogs
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ChatLogId { get; set; }
[Column("Message")]
public string Message { get; set; }
[Column("UserId")]
public int UserId { get; set; }
public override string ToString()
{
return "Person: " + Message + " " + UserId;
}
}
UserId in table ChatLogs is foreign key to UserPorfile UserId primary key.
I am trying to join these 2 tables in Asp.NET MVC 4
Tested SQL query:
select * from UserProfile as a join ChatLogs as b on a.UserId = b.UserId
Tested Linq query:
from b in db.ChatLogs
select new {
ChatLogId = b.ChatLogId,
Message = b.Message,
UserId = b.UserId,
Column1 = (int?)b.UserProfile.UserId,
UserName = b.UserProfile.UserName,
Email = b.UserProfile.Email
}
I am using software called "Linqer" for learning purposes. It conversts SQL to Linq.
ActionResult code:
private ChatLogContext db = new ChatLogContext();
public ActionResult Index()
{
var list = from b in db.ChatLogs
select new
{
ChatLogId = b.ChatLogId,
Message = b.Message,
UserId = b.UserId,
Column1 = (int?)b.UserProfile.UserId,
UserName = b.UserProfile.UserName,
Email = b.UserProfile.Email
};
var vm = new ChatLogsViewModel { LogListString = string.Join("\n", list) };
return View(vm);
}
ChatLogViewModel has only a string variable for printing list in view.
But I get an error:
'Chat.Models.ChatLogs' does not contain a definition for 'UserProfile' and no extension method 'UserProfile' accepting a first argument of type 'Chat.Models.ChatLogs' could be found (are you missing a using directive or an assembly reference?)
So do I have to connect those 2 entities somehow so they would know about each other?
Try this:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
**public virtual ICollection<ChatLogs> ChatLogs { get; set; }**
}
[Table("ChatLogs")]
public class ChatLogs
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ChatLogId { get; set; }
[Column("Message")]
public string Message { get; set; }
[Column("UserId")]
public int UserId { get; set; }
**public virtual UserProfile UserProfile { get;set; }**
public override string ToString()
{
return "Person: " + Message + " " + UserId;
}
}
The easiest way to connect is to make Chatlogs available on the user as a List:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public List<ChatLog> ChatLogs{ get; set;}
}
Now you can do the following:
var users = Users.Include("ChatLogs");
Every user will now have its list of ChatLogs filled in correctly.