How to insert payload data in many-to-many relationships with EF Core 5 - entity-framework

I have this relationship between Licitadores and Ofertas
public class Licitador
{
public int Id { get; set; }
public string Nombre { get; set; }
[StringLength(maximumLength: 15)]
public string CodigoSAP { get; set; }
public List<Oferta> Ofertas { get; set; } = new List<Oferta>();
}
public class Oferta
{
[StringLength(maximumLength:6)]
public string Id { get; set; }
[StringLength(maximumLength: 5)]
public string IdPresentada { get; set; }
....
public List<Licitador> Licitadores { get; set; } = new List<Licitador>();
}
And the join table in the context
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<LicitacionesEnSolitario>().ToTable("LicitacionesSolitario");
modelBuilder.Entity<Licitador>()
.HasMany(o => o.Ofertas)
.WithMany(of => of.Licitadores)
.UsingEntity<LicitacionesEnSolitario>
(oo => oo.HasOne<Oferta>().WithMany(),
oo => oo.HasOne<Licitador>().WithMany())
.Property(oo => oo.Adjudicado)
.IsRequired();
}
I need this data in my entity/table LicitacionesEnSolitario in addition to PK y FK
public class LicitacionesEnSolitario
{
public int LicitadorId { get; set; }
public string OfertaId { get; set; }
public bool Adjudicado { get; set; }
public string Plazo { get; set; }
public decimal PresupuestoOfertado { get; set; }
public DateTime? FechaAdjudicacion { get; set; }
}
Here I insert the data importing them from another database
public int ImportarLicitacionesEnSolitario()
{
try
{
int registrosAñadidos = 0;
var registrosSAP = _contextSAP.LicitacionesEnSolitario
.FromSqlRaw("sql")
.ToList();
foreach (var registroSAP in registrosSAP)
{
var oferta = _contextBoletus.Ofertas.Find(registroSAP.OfertaId);
var licitador = _contextBoletus.Licitadores.Where(l => l.CodigoSAP == registroSAP.CodigoSAP).FirstOrDefault();
oferta.Licitadores.Add(licitador);
registrosAñadidos +=1;
}
_contextBoletus.SaveChanges();
return registrosAñadidos;
}
catch (Exception ex)
{
throw ex;
}
}
This works fine and insert data in "LicitacionesEnSolitario" but with this fields Adjudicado, Plazo, PresupuestoPfertado y FechaAdjudicacion with nulls.
I don't know how to insert them at the time I insert Licitadores and if I try to update after the Add method using the PKs I just added
foreach (var registroSAP in registrosSAP)
{
var oferta = _contextBoletus.Ofertas.Find(registroSAP.OfertaId);
var licitador = _contextBoletus.Licitadores.Where(l => l.CodigoSAP == registroSAP.CodigoSAP).FirstOrDefault();
oferta.Licitadores.Add(licitador);
var ls = _contextBoletus.Set<LicitacionesEnSolitario>()
.SingleOrDefault(ls => ls.OfertaId == oferta.Id & ls.LicitadorId == licitador.Id);
ls.Adjudicado = registroSAP.Adjudicado;
ls.PresupuestoOfertado = registroSAP.PresupuestoOfertado;
ls.FechaAdjudicacion = registroSAP.FechaAdjudicacion;
registrosAñadidos +=1;
}
_contextBoletus.SaveChanges();
return registrosAñadidos;
I get this error System.NullReferenceException: Object reference not set to an instance of an object.
Any idea, please?
Thanks

This is the best way I found
foreach (var registroSAP in registrosSAP)
{
var oferta = _contextBoletus.Ofertas.Find(registroSAP.OfertaId);
var licitador = _contextBoletus.Licitadores.Where(l => l.CodigoSAP == registroSAP.CodigoSAP).FirstOrDefault();
var ls = _contextBoletus.Set<LicitacionesEnSolitario>().Add(
new LicitacionesEnSolitario
{
LicitadorId = licitador.Id,
OfertaId = oferta.Id,
Adjudicado = registroSAP.Adjudicado,
Plazo = registroSAP.Plazo,
PresupuestoOfertado = registroSAP.PresupuestoOfertado,
FechaAdjudicacion = registroSAP.FechaAdjudicacion
});
registrosAñadidos += 1;
}
Thanks

Related

Return entity with sub table collection

Here is what I have:
public class StudentHealthInfoType
{
public int StudentHealthInfoId { get; set; }
public bool? HasAllergies { get; set; }
public List<HealthInfoMedicationType> HealthInfoMedicationType { get; set;}
}
public class HealthInfoMedicationType
{
public int HealthInfoMedicationId { get; set; }
public string MedicationName { get; set; }
}
var result = (from u in context.StudentHealthInfos
from m in context.HealthInfoMedications
where u.RegistrationId == registrationId
&& u.StudentHealthInfoId == m.StudentHealthInfoId
select new StudentHealthInfoType
{ StudentHealthInfoId = u.StudentHealthInfoId,
HasAllergies = u.HasAllergies, HealthInfoMedicationType = new HealthInfoMedicationType
{ HealthInfoMedicationId = m.HealthInfoMedicationId,
MedicationName = m.MedicationName
}
}).FirstOrDefault();
I get this error which is show at HealthInfoMedicationType = new HealthInfoMedicationType
Cannot implicitly convert type
'Dis.QueryManager.HealthFormTypes.HealthInfoMedicationType' to
'System.Collections.Generic.List'
HealthInfoMedicationType needs to be a collection of items returned for one StudentHealthInfoType record. How do I need to setup my objects and then cast them so this query works?
Please try this if you want to query for a particular registration id and list of HealthInfoMedications you can do like this .
var result = context.StudentHealthInfos
.Include(x=>x.HealthInfoMedicationType).FirstOrDefault(f => f.RegistrationId == 1);
// Result will be StudentHealthInfoType with list of HealthInfoMedicationType

Saving one entity having m-t-m relationship duplicate the other entity in the DB?

I have two entities with many to many relationship, I'm saving one entity that has a list of entities, but they get duplicated
ex:
class GENEntity
{
int Id { get; set; }
string Name { get; set; }
List<GENEntityTab> tabs { get; set; }
}
class GENEntityTab
{
int Id { get; set; }
string Name { get; set; }
List<GENEntity> entities { get; set; }
}
When I save object of GENEntity but as a view model as you'll see next, with a list of two GENEntityTab, those two tabs get inserted (duplicated) in the DB. I'm using Web API and angular
In the Repository, it's only called when I click submit (there are some extra properties):
public static JsonViewData AddOrUpdate(ModelDBContext context, GENEntityViewModel entityVM, string name, string id)
{
try
{
var entity = context.Entities.SingleOrDefault(x => x.Id == entityVM.Id);
if (entity == null)
{
entity = new GENEntity();
entity.InjectFrom(entityVM);
context.Entities.Add(entity);
}
else
{
entity.DateUpdated = DateTime.Now;
entity.InjectFrom(entityVM);
}
entity.CreatedById = new Guid(id);
entity.LastUpdatedById = new Guid(id);
context.SaveChanges();
return new JsonViewData { IsSuccess = true, Message = "Created Successfully" };
}
catch (Exception ex)
{
return new JsonViewData { IsSuccess = false, Message = ex.Message };
}
}
the view models:
public class GENEntityTabViewModel
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<GENEntity> Entities { get; set; } = new List<GENEntity>();
public GENEntityTabViewModel()
{
}
public GENEntityTabViewModel(GENEntityTab entityTab)
{
Id = entityTab.Id;
Name = entityTab.Name;
Description = entityTab.Description;
Entities = entityTab.Entities;
}
}

EF6: Single relationship table for multiple related entities

I have a EF Model with many entities, like Nodes, Attributes, Tags, etc.
There is also an "Alias" entity, and pretty much every other entity else can have a many-to-many relationship with Aliases. One of the undesired things about this is the number of tables that are created to track these relationships (eg. NodeAlias, AttributeAlias, etc.).
Are there any design alternatives that could map an Alias to all of the other entities in a single table? I was thinking maybe something along these lines if it's possible:
+---------+--------+-------------+-----------+
| AliasId | NodeId | AttributeId | TagId |
+---------+--------+-------------+-----------+
| 1 | 1 | 2 | 3 |
+---------+--------+-------------+-----------+
I updated my solution to provide many-to-many relationships between aliases and every other entity.
I intentionally posted this as a separate answer so that my previous answer can also remain here if anyone would need it.
Step #1: I created extension methods for getting and setting property values using reflection in a convenient way:
public static class ObjectExtensions
{
public static TResult GetPropertyValue<TResult>(this object entity, string propertyName)
{
object propertyValue = entity?.GetType().GetProperty(propertyName)?.GetValue(entity);
try
{
return (TResult)propertyValue;
}
catch
{
return default(TResult);
}
}
public static void SetPropertyValue(this object entity, string propertyName, object value)
{
entity?.GetType().GetProperty(propertyName)?.SetValue(entity, value);
}
}
Step #2: I updated the models to provide many-to-many relationship.
public class Node
{
[Key]
public int NodeId { get; set; }
public string Name { get; set; }
public virtual ICollection<AliasMapping> AliasMappings { get; set; }
}
public class Attribute
{
[Key]
public int AttributeId { get; set; }
public string Name { get; set; }
public virtual ICollection<AliasMapping> AliasMappings { get; set; }
}
public class Tag
{
[Key]
public int TagId { get; set; }
public string Name { get; set; }
public virtual ICollection<AliasMapping> AliasMappings { get; set; }
}
public class Alias
{
[Key]
public int AliasId { get; set; }
public string Name { get; set; }
public virtual ICollection<AliasMapping> AliasMappings { get; set; }
}
public class AliasMapping
{
[Key]
public int Id { get; set; }
[ForeignKey("Alias")]
public int AliasId { get; set; }
public Alias Alias { get; set; }
[ForeignKey("Node")]
public int? NodeId { get; set; }
public virtual Node Node { get; set; }
[ForeignKey("Attribute")]
public int? AttributeId { get; set; }
public virtual Attribute Attribute { get; set; }
[ForeignKey("Tag")]
public int? TagId { get; set; }
public virtual Tag Tag { get; set; }
}
Step #3: Due to relationship changes the MyDbContext could have been simplified as the [ForeignKey] data annotations are enough.
public class MyDbContext : DbContext
{
public DbSet<Node> Nodes { get; set; }
public DbSet<Attribute> Attributes { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<Alias> Aliases { get; set; }
public DbSet<AliasMapping> AliasMappings { get; set; }
}
Step #4: I also updated the extension methods so that you can create and remove alias mappings.
public static class AliasExtensions
{
public static void CreateMapping(this MyDbContext context, object entity, Alias alias)
{
if (entity == null || alias == null)
{
return;
}
string mappingEntityPropertyName = entity.GetType().Name;
string entityKeyPropertyName = String.Concat(mappingEntityPropertyName, "Id");
int entityId = entity.GetPropertyValue<int>(entityKeyPropertyName);
AliasMapping[] mappings =
context
.AliasMappings
.Where(mapping => mapping.AliasId == alias.AliasId)
.ToArray();
if (mappings.Any(mapping => mapping.GetPropertyValue<int?>(entityKeyPropertyName) == entityId))
{
// We already have the mapping between the specified entity and alias.
return;
}
bool usableMappingExists = true;
var usableMapping = mappings.FirstOrDefault(mapping => mapping.GetPropertyValue<int?>(entityKeyPropertyName) == null);
if (usableMapping == null)
{
usableMappingExists = false;
usableMapping = new AliasMapping()
{
Alias = alias
};
}
usableMapping.SetPropertyValue(mappingEntityPropertyName, entity);
usableMapping.SetPropertyValue(entityKeyPropertyName, entityId);
if (!usableMappingExists)
{
context.AliasMappings.Add(usableMapping);
}
// This step is required here, I think due to using reflection.
context.SaveChanges();
}
public static void RemoveMapping(this MyDbContext context, object entity, Alias alias)
{
if (entity == null || alias == null)
{
return;
}
string mappingEntityPropertyName = entity.GetType().Name;
string entityKeyPropertyName = String.Concat(mappingEntityPropertyName, "Id");
int entityId = entity.GetPropertyValue<int>(entityKeyPropertyName);
AliasMapping[] mappings =
context
.AliasMappings
.Where(mapping => mapping.AliasId == alias.AliasId)
.ToArray();
AliasMapping currentMapping = mappings.FirstOrDefault(mapping => mapping.GetPropertyValue<int?>(entityKeyPropertyName) == entityId);
if (currentMapping == null)
{
// There is no mapping between the specified entity and alias.
return;
}
currentMapping.SetPropertyValue(mappingEntityPropertyName, null);
currentMapping.SetPropertyValue(entityKeyPropertyName, null);
// This step is required here, I think due to using reflection.
context.SaveChanges();
}
}
Step #5: Updated the console app steps to align it with the changes.
class Program
{
static void Main(string[] args)
{
// Consider specify the appropriate database initializer!
// I use DropCreateDatabaseAlways<> strategy only for this example.
Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());
var aliases =
Enumerable
.Range(1, 9)
.Select(index => new Alias() { Name = String.Format("Alias{0:00}", index) })
.ToList();
var attributes =
Enumerable
.Range(1, 5)
.Select(index => new Attribute() { Name = String.Format("Attribute{0:00}", index) })
.ToList();
var nodes =
Enumerable
.Range(1, 5)
.Select(index => new Node() { Name = String.Format("Node{0:00}", index) })
.ToList();
var tags =
Enumerable
.Range(1, 5)
.Select(index => new Tag() { Name = String.Format("Tag{0:00}", index) })
.ToList();
using (var context = new MyDbContext())
{
context.Aliases.AddRange(aliases);
context.Nodes.AddRange(nodes);
context.Attributes.AddRange(attributes);
context.Tags.AddRange(tags);
// Always save changes after adding an entity but before trying to create a mapping.
context.SaveChanges();
// One Alias To Many Entities
context.CreateMapping(nodes[0], aliases[0]);
context.CreateMapping(nodes[1], aliases[0]);
context.CreateMapping(nodes[2], aliases[0]);
context.CreateMapping(nodes[3], aliases[0]);
context.CreateMapping(attributes[0], aliases[0]);
context.CreateMapping(attributes[1], aliases[0]);
context.CreateMapping(attributes[2], aliases[0]);
context.CreateMapping(tags[0], aliases[0]);
context.CreateMapping(tags[1], aliases[0]);
// One Entity To Many Aliases
context.CreateMapping(nodes[4], aliases[0]);
context.CreateMapping(nodes[4], aliases[1]);
context.CreateMapping(nodes[4], aliases[2]);
context.CreateMapping(attributes[3], aliases[1]);
context.CreateMapping(attributes[3], aliases[3]);
context.CreateMapping(tags[2], aliases[2]);
context.CreateMapping(tags[2], aliases[3]);
// Remove mapping
context.RemoveMapping(nodes[4], aliases[0]);
// Not really needed here as both 'CreateMapping' and 'RemoveMapping' save the changes
context.SaveChanges();
}
Console.Write("Press any key to continue . . .");
Console.ReadKey(true);
}
}
Please note: RemoveMapping() will not delete an AliasMapping even if no entity is associated with it! But CreateMapping() will make use of it later if needed. E.g. look at the screenshot below and check AliasMapping where Id = 5.
Screenshot about the execution result:
You were talking about many-to-many relationship but reading your post I think it is more likely a "special one-to-many" relationship, actually "combined multiple one-to-one" relationship as I see that an Alias can be mapped to a single Node AND/OR to a single Attribute AND/OR to a single Tag.
I think I found a solution for this case.
If it's not the case and an Alias can be mapped to multiple Node AND/OR to multiple Attribute AND/OR to multiple Tag then I think this solution below needs only a small change. :)
Step #1 - These are my example models
public class Node
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual AliasMapping AliasMapping { get; set; }
}
public class Attribute
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual AliasMapping AliasMapping { get; set; }
}
public class Tag
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual AliasMapping AliasMapping { get; set; }
}
public class Alias
{
[Key]
public int AliasId { get; set; }
public string Name { get; set; }
public virtual AliasMapping AliasMapping { get; set; }
}
Step #2 - Creating the custom mapping table
public class AliasMapping
{
[Key]
[ForeignKey("Alias")]
public int AliasId { get; set; }
public Alias Alias { get; set; }
[ForeignKey("Node")]
public int NodeId { get; set; }
public virtual Node Node { get; set; }
[ForeignKey("Attribute")]
public int AttributeId { get; set; }
public virtual Attribute Attribute { get; set; }
[ForeignKey("Tag")]
public int TagId { get; set; }
public virtual Tag Tag { get; set; }
}
Step #3 - Creating the DbContext
public class MyDbContext : DbContext
{
public DbSet<Node> Nodes { get; set; }
public DbSet<Attribute> Attributes { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<Alias> Aliases { get; set; }
public DbSet<AliasMapping> AliasMappings { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder
.Entity<AliasMapping>()
.HasOptional(mapping => mapping.Attribute)
.WithOptionalPrincipal(attribute => attribute.AliasMapping)
.Map(config => config.MapKey("AliasId"));
modelBuilder
.Entity<AliasMapping>()
.HasOptional(mapping => mapping.Node)
.WithOptionalPrincipal(node => node.AliasMapping)
.Map(config => config.MapKey("AliasId"));
modelBuilder
.Entity<AliasMapping>()
.HasOptional(mapping => mapping.Tag)
.WithOptionalPrincipal(tag => tag.AliasMapping)
.Map(config => config.MapKey("AliasId"));
}
}
Step #4 - Creating extension method so that creating a relationship will be easy
public static class AliasExtensions
{
public static void CreateMapping<TEntity>(this MyDbContext context, TEntity entity, Alias alias)
{
string mappingEntityPropertyName = typeof(TEntity).Name;
string entityKeyPropertyName = String.Concat(mappingEntityPropertyName, "Id");
bool entityExists = true;
var mapping = context.AliasMappings.Find(alias.AliasId);
if (mapping == null)
{
entityExists = false;
mapping = new AliasMapping()
{
Alias = alias
};
}
typeof(AliasMapping)
.GetProperty(mappingEntityPropertyName)
.SetValue(mapping, entity);
typeof(AliasMapping)
.GetProperty(entityKeyPropertyName)
.SetValue(mapping, typeof(TEntity).GetProperty("Id").GetValue(entity));
if (!entityExists)
{
context.AliasMappings.Add(mapping);
}
}
}
Step #5 - Created a console app to see this working
class Program
{
static readonly Random rnd = new Random(DateTime.Now.TimeOfDay.Milliseconds);
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());
var aliases =
Enumerable
.Range(1, 9)
.Select(index => new Alias() { Name = String.Format("Alias{0:00}", index) })
.ToList();
var attributes =
Enumerable
.Range(1, 5)
.Select(index => new Attribute() { Name = String.Format("Attribute{0:00}", index) })
.ToList();
var nodes =
Enumerable
.Range(1, 5)
.Select(index => new Node() { Name = String.Format("Node{0:00}", index) })
.ToList();
var tags =
Enumerable
.Range(1, 5)
.Select(index => new Tag() { Name = String.Format("Tag{0:00}", index) })
.ToList();
using (var context = new MyDbContext())
{
context.Aliases.AddRange(aliases);
context.Nodes.AddRange(nodes);
context.Attributes.AddRange(attributes);
context.Tags.AddRange(tags);
context.SaveChanges();
// Associate aliases to attributes
attributes.ForEach(attribute =>
{
var usableAliases = aliases.Where(alias => alias.AliasMapping?.Attribute == null).ToList();
var selectedAlias = usableAliases[rnd.Next(usableAliases.Count)];
context.CreateMapping(attribute, selectedAlias);
});
// Associate aliases to nodes
nodes.ForEach(node =>
{
var usableAliases = aliases.Where(alias => alias.AliasMapping?.Node == null).ToList();
var selectedAlias = usableAliases[rnd.Next(usableAliases.Count)];
context.CreateMapping(node, selectedAlias);
});
// Associate aliases to tags
tags.ForEach(tag =>
{
var usableAliases = aliases.Where(alias => alias.AliasMapping?.Tag == null).ToList();
var selectedAlias = usableAliases[rnd.Next(usableAliases.Count)];
context.CreateMapping(tag, selectedAlias);
});
context.SaveChanges();
}
Console.Write("Press any key to continue . . .");
Console.ReadKey(true);
}
}

MVC4 Entity Framework Controller Database Issue

I am trying to perform an insert or update from my controller but I get an error message stating that 'ICN.CourierClient does not contain a definition' of my various properties like 'Address' - when in fact it does, and my other similar calls to other database models work fine with the same code. Did I miss a reference or some configuration somewhere, I have it defined in the same way as my other models in my dbset statements:
public DbSet<Courier> Couriers { get; set; }
public DbSet<Driver> Drivers { get; set; }
public DbSet<Job> Jobs { get; set; }
public DbSet<CourierClient> CourierClients { get; set; }
IQueryable<Courier> Datasource.Couriers { get { return Couriers; } }
IQueryable<Driver> Datasource.Drivers { get { return Drivers; } }
IQueryable<Job> Datasource.Jobs { get { return Jobs; } }
IQueryable<CourierClient> Datasource.CourierClients { get { return CourierClients; } }
IEnumerable<CourierClient> client = null;
client = from c in db.CourierClients where c.ClientName == job.PickupCompanyName select c;
if (client != null)
{
client.Address = job.PickupAddress1;
client.City = job.PickupCity;
client.State = job.PickupState;
client.Zip = job.PickupZip;
client.Phone = job.PickupPhone;
db.Entry(client).State = EntityState.Modified;
}
else
{
client.ClientName = job.PickupCompanyName;
client.Address = job.PickupAddress1;
client.City = job.PickupCity;
client.State = job.PickupState;
client.Zip = job.PickupZip;
client.Phone = job.PickupPhone;
db.CourierClients.Add(client);
}
db.SaveChanges();
public class CourierClient
{
[Key]
public virtual int ID { get; set; }
public virtual string ClientName { get; set; }
public virtual string ContactName { get; set; }
public virtual string Address { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
public virtual string Zip { get; set; }
public virtual string Phone { get; set; }
public virtual string Fax { get; set; }
public virtual string Email { get; set; }
}
You declared client as IEnumerable<CourierClient>. That is why compiler tells you that it does not have properties, which you expect to find in CourierClient.
CourierClient client = (from c in db.CourierClients where c.ClientName == job.PickupCompanyName select c).SingleOrDefault();
if (client != null)
{
client.Address = job.PickupAddress1;
client.City = job.PickupCity;
client.State = job.PickupState;
client.Zip = job.PickupZip;
client.Phone = job.PickupPhone;
db.Entry(client).State = EntityState.Modified;
}
else
{
client = new CourierClient();
client.ClientName = job.PickupCompanyName;
client.Address = job.PickupAddress1;
client.City = job.PickupCity;
client.State = job.PickupState;
client.Zip = job.PickupZip;
client.Phone = job.PickupPhone;
db.CourierClients.Add(client);
}
db.SaveChanges();
Note the creation of the instance of CourierClient if it was not found.

Update list object based on other LINQ / LAMBDA

Here are my two objects
public class ObjectHeaderBuffer
{
public int DataObjectId { get; set; }
public string FileName { get; set; }
public int RowCount { get; set; }
public string Checksum { get; set; }
public int ReconTarget { get; set; }
}
public class ObjectHeaderAttribute
{
public int DataObjectId { get; set; }
public int AttributeType { get; set; }
public int AttributeValue { get; set; }
}
var ohBuffer = new List<ObjectHeaderBuffer>();
var ohAttribute = new List<ObjectHeaderAttribute>();
I want to update ohBuffer.ReconTarget with ohAttribute.AttributeValue where ohBuffer.DataObjectId == ohAttribute.DataObjectId
what is linq or lambda of this?
You need to iterate each item in ohBuffer and look up the value in ohAttribute.
Assuming there is only one Attribute for each Buffer, this will work.
ohBuffer.ForEach(b => b.ReconTarget = ohAttribute
.SingleOrDefault(a => a.DataObjectId == b.DataObjectId).AttributeValue);
If the lookup returns null, you can either coalesce to a new object and take the default value
ohBuffer.ForEach(b => b.ReconTarget =
(ohAttribute.SingleOrDefault(a => a.DataObjectId == b.DataObjectId)
?? new ObjectHeaderAttribute())
.AttributeValue);
or you could just take null
ohBuffer.ForEach(b => b.ReconTarget =
{
var attribute = ohAttribute
.SingleOrDefault(a => a.DataObjectId == b.DataObjectId);
if (attribute == null)
return null;
return attribute.AttributeValue;
});
They way i did is:
foreach (var objectHeaderBuffer in ohBuffer)
{
var objectHeaderAttribute = (from c in ohAttribute where c.DataObjectId == objectHeaderBuffer.DataObjectId select c).First();
objectHeaderBuffer.ReconTarget = objectHeaderAttribute.AttributeValue;
}
If your relation is 1:1 Then
foreach (ObjectHeaderBuffer Itemx in ohBuffer)
{
ObjectHeaderAttribute Itemy= (from ObjectHeaderAttribute c in ohAttribute where c.DataObjectId == Itemx.DataObjectId select c).FirstOrDefault();
if(Itemy!=null)
{
Itemx .ReconTarget = Itemy.AttributeValue;
}
}
Or
foreach (ObjectHeaderBuffer Itemx in ohBuffer)
{
ObjectHeaderAttribute Itemy= ohAttribute.Where(c=>c.DataObjectId == Itemx .DataObjectId).FirstOrDefault();
if(Itemy!=null)
{
Itemx .ReconTarget = Itemy.AttributeValue;
}
}